2012-07-16 13 views
6

Ho una semplice app che genera una serie di attività intensive. Non ho molta esperienza con WinForms e mi chiedevo il modo migliore per farlo senza bloccare l'interfaccia. È possibile riutilizzare backgroundWorker o esiste un altro modo per farlo?Multithreading WinForm. Usa backgroundWorker o no?

Grazie

+0

Vorrei utilizzare il backgroundworker. – Tomtom

+0

Se hai bisogno di un altro thread, utilizzerei un worker in background, sono molto facili da usare e gran parte del lavoro è stato fatto, offrendoti eventi diretti per le diverse fasi del completamento del lavoro. – ThePower

+0

Cosa intendi riutilizzando? –

risposta

6

backgroundWorkerpuò essere utilizzato.

il vantaggio: consente di aggiornare una barra di avanzamento e interagire con i controlli dell'interfaccia utente. (WorkerReportsProgress)

Inoltre ha un meccanismo di cancellazione. (WorkerSupportsCancellation)

enter image description here

3

BackgroundWorker è un filo che include anche la sincronizzazione di notifica. Ad esempio, se si desidera aggiornare l'interfaccia utente al termine della scansione, un normale Thread non può accedere agli oggetti dell'interfaccia utente (solo il thread dell'interfaccia utente può farlo); quindi, BackgroundWorker fornisce un gestore eventi Completato che viene eseguito sul thread dell'interfaccia utente al termine dell'operazione.

Per maggiori informazioni visita: Walkthrough: Multithreading with the BackgroundWorker Component(MSDN)

e di un codice di esempio semplice:

var worker = new System.ComponentModel.BackgroundWorker(); 
worker.DoWork += (sender,e) => Thread.Sleep(60000); 
worker.RunWorkerCompleted += (sender,e) => MessageBox.Show("Hello there!"); 
worker.RunWorkerAsync(); 
2

È possibile utilizzare BackgroundWorker per tali esigenze. Di seguito è un esempio che updates a label status based on percentage task [long running] completion. Inoltre, esiste una classe aziendale di esempio che imposta un valore e il valore viene reimpostato nell'interfaccia utente tramite il gestore ProgressChanged. DoWork è il posto in cui si scrive la logica dell'attività a esecuzione prolungata. Copia-incolla il codice qui sotto dopo aver aggiunto un componente label e backgroundworker su un'app Winforms & dagli un colpo. È possibile eseguire il debug su vari handler [RunWorkerCompleted, ProgressChanged, DoWork] e dare un'occhiata al metodo InitWorker. Notare anche lo cancellation feature.

using System.ComponentModel; 
using System.Windows.Forms; 

namespace WindowsFormsApplication1 
{ 
    public partial class Form3 : Form 
    { 
     private BackgroundWorker _worker; 
     BusinessClass _biz = new BusinessClass(); 
     public Form3() 
     { 
      InitializeComponent(); 
      InitWorker(); 
     } 

     private void InitWorker() 
     { 
      if (_worker != null) 
      { 
       _worker.Dispose(); 
      } 

      _worker = new BackgroundWorker 
      { 
       WorkerReportsProgress = true, 
       WorkerSupportsCancellation = true 
      }; 
      _worker.DoWork += DoWork; 
      _worker.RunWorkerCompleted += RunWorkerCompleted; 
      _worker.ProgressChanged += ProgressChanged; 
      _worker.RunWorkerAsync(); 
     } 


     void DoWork(object sender, DoWorkEventArgs e) 
     { 
      int highestPercentageReached = 0; 
      if (_worker.CancellationPending) 
      { 
       e.Cancel = true; 
      } 
      else 
      { 
       double i = 0.0d; 
       int junk = 0; 
       for (i = 0; i <= 199990000; i++) 
       { 
        int result = _biz.MyFunction(junk); 
        junk++; 

        // Report progress as a percentage of the total task. 
        var percentComplete = (int)(i/199990000 * 100); 
        if (percentComplete > highestPercentageReached) 
        { 
         highestPercentageReached = percentComplete; 
         // note I can pass the business class result also and display the same in the LABEL 
         _worker.ReportProgress(percentComplete, result); 
         _worker.CancelAsync(); 
        } 
       } 

      } 
     } 

     void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
     { 
      if (e.Cancelled) 
      { 
       // Display some message to the user that task has been 
       // cancelled 
      } 
      else if (e.Error != null) 
      { 
       // Do something with the error 
      } 
     } 

     void ProgressChanged(object sender, ProgressChangedEventArgs e) 
     { 
      label1.Text = string.Format("Result {0}: Percent {1}",e.UserState, e.ProgressPercentage); 
     } 
    } 

    public class BusinessClass 
    { 
     public int MyFunction(int input) 
     { 
      return input+10; 
     } 
    } 
} 
+0

Grazie per la risposta dettagliata. La mia preoccupazione è di aggiungere la mia "logica dell'attività a lungo termine" all'evento DoWork.Ho un numero di attività che devono essere eseguite e non sembra pratico aggiungerle tutte all'evento DoWork. – Brian