2015-04-27 8 views
5

Si prega di tenere conto della mia ignoranza su questo argomento e sulla terminologia che ho usato. Per favore correggimi dove sono errato.Passare un altro metodo/funzione all'evento DoWork di Background worker

Ho utilizzato un Worker in background dalla toolbox sul mio modulo e sto passando un metodo all'evento DoWork. Quello che ho capito in questo primo tentativo con Background Worker è che posso usare lo sfondo Worker che ho creato solo per 1 attività. Vedere codice qui sotto:

private void btn1_Click(object sender, EventArgs e) 
{ 
    // Should call the uploadToDB1 using BackgroundWorker's DoWork event. 
    backgroundWorker1.RunWorkerAsync(); 
} 

private void btn2_Click(object sender, EventArgs e) 
{ 
    // Should call the uploadToDB2 using BackgroundWorker's DoWork event. 
    backgroundWorker1.RunWorkerAsync(); 
} 

private void uploadToDB1() 
{ 
    // Code for uploading to DB 1. 
}   

private void uploadToDB2() 
{ 
    // Code for uploading to DB 2. 
} 

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
{ 
    try 
    { 

     uploadToDB1(); // I want to change this to uploadToDB2 i.e. a variable method, How do I assign a call to this? 

    } 
    catch (Exception ex) 
    { 

     MessageBox.Show(ex.Message); 
    } 

} 

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) 
{ 
    progressBar1.Visible = true; 
    progressBar1.Maximum = maxRecords; 
    lblProgress.Text = Convert.ToString(e.ProgressPercentage.ToString() + "/" + maxRecords); 
    progressBar1.Value = e.ProgressPercentage; 

} 

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    progressBar1.Visible = false; 
    lblProgress.Text = ""; 
} 

ho bisogno di essere in grado di passare dinamicamente un metodo per l'evento DoWork senza avere la necessità di creare più lavoratori di fondo come le azioni nel resto degli eventi legati al fondo dei lavoratori rimane invariato .

Potresti consigliare come dovrei procedere?

Codice aggiornato utilizzando TPL, tuttavia sto ottenendo un errore di thread incrociato. Potresti per favore aiutare con un codice corretto? Il caricamento su DB 2 dovrebbe avvenire solo dopo il caricamento su DB 1. Pertanto, ogni volta che si verifica un caricamento, è necessario aggiornare l'etichetta e la barra di avanzamento. Devo anche passare un testo diverso all'etichetta.

private void btn1_Click(object sender, EventArgs e) 
{ 
    Task.Factory.StartNew(uploadToDB1); 
} 
private void uploadToDB1() 
{ 
    for(i=0;i<dt.rows.count-1;i++) 
    { 
     // Code for inserting into DB1. 

     progressbar1.maximum=dt.rows.count-1; 
     progressbar1.value=i; 
    } 
    uploadToDB2(); 

} 

private void uploadToDB2() 
{ 
    for(i=0;i<dt.rows.count-1;i++) 
    { 
     // Code for inserting into DB2. 

     progressbar1.maximum=dt.rows.count-1; 
     progressbar1.value=i; 
    } 

} 
+1

Perché non creare due operai di sfondo, uno per ogni posto di lavoro? –

+0

Perché non buttare semplicemente "BackgroundWorker" e usare TPL? –

+0

Un modello di strategia può aiutare anche voi –

risposta

1

Cosa si possibile fare, ed è un po 'di hack, è passare un Action come un argomento per invocazione al DoWorkAsync:

var bw = new BackgroundWorker(); 
bw.DoWork += (s, o) => 
{ 
    Action actualWork = (Action)o.Argument; 
    actualWork(); 
} 

e quando si richiama DoWorkAsync:

Action action =() => DoSomething(); 
bw.RunWorkerAsync(action); 

Invece, come suggerito da @Sriram, guarda nello Task Parallel Library, che ti farà vita un po 'più facile:

private async void btn1_Click(object sender, EventArgs e) 
{ 
    await Task.Run(UpdateFirst); 
    // Update UI here. 
} 

private async void btn2_Click(object sender, EventArgs e) 
{ 
    await Task.Run(UpdateSecond); 
    // Update UI again. 
} 

Una risposta ampia sul TPL e l'uso di IProgess<T> può essere trovato in How to provide a feedback to UI in a async method?

+0

Ci sono due [risposte qui] (http://stackoverflow.com/q/25745176/2530848) che riassume molto bene ciò che OP vuole. Usa 'IProgress ' con TPL per fornire feedback all'interfaccia utente. –

+0

@SriramSakthivel Ora me lo dici? : \ –

+0

Per la comunità :) –

Problemi correlati