it-swarm.it

C # dovrei creare un lavoratore in background o molti?

Sono uno di quei programmatori casuali, quindi non ho molte conoscenze sulla programmazione delle migliori pratiche.

Ho un'applicazione che attualmente utilizza 4 Background Worker.

Quindi li dichiaro:

private BackgroundWorker bw1;
private BackgroundWorker bw2;
private BackgroundWorker bw3;
private BackgroundWorker bw4;

Quindi configurale:

bw1 = new BackgroundWorker();
bw1.WorkerReportsProgress = true;
bw1.DoWork += new DoWorkEventHandler(bw1_DoWork);
bw1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw1_RunWorkerCompleted);
bw1.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);

bw2 = new BackgroundWorker();
bw2.WorkerReportsProgress = true;
bw2.DoWork += new DoWorkEventHandler(bw2_DoWork);
bw2.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw2_RunWorkerCompleted);
bw2.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);

bw3 = new BackgroundWorker();
bw3.WorkerReportsProgress = true;
bw3.DoWork += new DoWorkEventHandler(bw3_DoWork);
bw3.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw3_RunWorkerCompleted);
bw3.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);

bw4 = new BackgroundWorker();
bw4.WorkerReportsProgress = true;
bw4.DoWork += new DoWorkEventHandler(bw4_DoWork);
bw4.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw4_RunWorkerCompleted);
bw4.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);

E poi uso bw1.RunWorkerAsync (), bw2.RunWorkerAsync () e così via ...

Il fatto è che non li chiamo mai contemporaneamente, sono chiamati in punti diversi in modo piuttosto lineare.

Quindi la mia domanda è: è meglio avere molti utenti in background "pre-configurati" o averne uno e modificare gli eventi DoWork ed RunWorkerCompleted in base a ciò che voglio che faccia?

23
Alex

Da un punto di vista architettonico, è meglio avere un lavoratore in background separato per ogni attività in background, che è logicamente estraneo a un altro compito della classe.

23
Maxim V. Pavlov

Di solito uso gli addetti allo sfondo in un modello abbastanza diverso. Invece di definirli tutti in una volta all'inizio inclusi i rispettivi gestori di eventi, li creo al volo quando faccio qualcosa che ne ha bisogno.

public void SomeEventHandlerMaybe(object sender, EventArgs e) {
  // do something

  var bw = new BackgroundWorker();
  bw.ReportsProgress = true;
  bw.DoWork += delegate {
    // do work. You can use locals from here
  };
  bw.ProgressChanged += delegate { ... };
  bw.RunWorkerCompleted += delegate {
    // do something with the results.
  };
  bw.RunWorkerAsync();
}

Qualcosa del genere. Ha il vantaggio di avere tutto il codice che fa qualcosa con o nel lavoratore in background in un posto e all'incirca nell'ordine giusto.

26
Joey

In genere è ragionevole utilizzare più thread se aiuta a utilizzare in modo più efficiente le risorse sul sistema. Per le attività a uso intensivo della CPU, un thread per core della CPU è un buon punto di partenza. Per IO attività intensive, puoi sicuramente averne molte di più.

Se hai la flessibilità di utilizzare .NET 4, cercherò nella Task Libreria parallela invece di BackgroundWorker. Per impostazione predefinita, prenderà decisioni relativamente intelligenti sul numero di thread da eseguire contemporaneamente oltre a fornire un modello di programmazione più semplice.

4
Eric J.

Effettuare l'elaborazione utilizzando BackgroundWorker significa che lo fai in un thread separato. Quindi, se non hai bisogno di multithreading, non c'è bisogno di addetti ai lavori separati. Se attendi il completamento dopo aver avviato ciascuno dei tuoi dipendenti, puoi avere un solo lavoratore. Potrebbe anche rimuovere parte della duplicazione del codice ...

0
Amittai Shapira

Esegui i lavoratori per qualche scopo computazionale. Se il calcolo di una chiamata viene utilizzato o dipende in un modo diverso da un altro, è possibile utilizzare più di un lavoratore, al fine di ottenere prestazioni migliori (dal modo in cui questo è troppo soggetto per la misurazione). Se hai solo bisogno di 4 lavori, e li esegui in un thread separato solo per non bloccare l'interfaccia utente principale, un lavoratore è una buona soluzione.

0
Tigran