Heim  >  Artikel  >  Backend-Entwicklung  >  Detaillierte Erläuterung der Verwendung von BackgroundWorker in C# (Bild)

Detaillierte Erläuterung der Verwendung von BackgroundWorker in C# (Bild)

黄舟
黄舟Original
2017-04-13 09:58:112534Durchsuche

In diesem Artikel wird hauptsächlich die Verwendung von C# BackgroundWorker ausführlich erläutert. Der Herausgeber findet ihn recht gut, daher werde ich ihn jetzt mit Ihnen teilen und als Referenz verwenden. Folgen wir dem Editor und werfen wir einen Blick darauf.

In C#-Programmen gibt es oft einige CPU-intensive Vorgänge, die lange dauern. Wenn solche Vorgänge direkt im UI-Thread ausgeführt werden, tritt das Problem auf, dass die Benutzeroberfläche nicht reagiert geschehen. . Die Hauptmethode zur Lösung dieser Art von Problemen besteht darin, Multithreading zu verwenden, einen Hintergrundthread zu starten und die Rechenoperationen in diesem Hintergrundthread abzuschließen. Der Thread-Betrieb der nativen Schnittstelle ist jedoch etwas schwierig. Wenn Sie die Kommunikation zwischen Threads weiter vervollständigen möchten, wird es noch schwieriger.

Glücklicherweise bietet die .NET -Klassenbibliothek eine Klasse namens BackgroundWorker, die diese Art von Problem eleganter lösen kann. Obwohl die BackgroundWorker-Klasse relativ einfach zu verwenden ist, müssen dennoch einige Details beachtet werden. Im Folgenden stellen wir ihre Hauptverwendung anhand des Demoprogramms vor. Wir berechnen die kumulative Summe von 1 bis 100 in der Demo. Zur Demonstration ruht jede Berechnung für 600 Millisekunden. Die Benutzeroberfläche der Demo ist:

Nutzungsübersicht

Erstellen Sie eine BackgroundWorker-Instanz auf dem Formular, fügen Sie zeitaufwändige Vorgänge zu ihrer DoWork-Ereignisbehandlungsfunktion hinzu und rufen Sie dann ihre RunWorkerAsync-Methode auf.

private BackgroundWorker _demoBGWorker = new BackgroundWorker();
_demoBGWorker.DoWork += BGWorker_DoWork;
_demoBGWorker.RunWorkerAsync();
private void BGWorker_DoWork(object sender, DoWorkEventArgs e)
{
  //在这里执行耗时的运算。
  int sum = 0;
  for (int i = 0; i <= 100; i++)
  {
    sum += i;
  }
}
Ist es nicht ein bisschen zu einfach? Betrachten wir also die folgende Frage:

Was ist, wenn wir Parameter an die Operation übergeben möchten?


Was sollen wir tun, wenn wir während des Berechnungsprozesses Echtzeitinformationen auf der Benutzeroberfläche anzeigen möchten?


Was ist, wenn wir den laufenden Vorgang abbrechen möchten?


Was sollen wir tun, wenn während des Vorgangs eine Ausnahme auftritt?

Als nächstes werden wir diese Probleme einzeln behandeln.

Übergeben Sie Parameter an den Berechnungsprozess

Es ist nicht gut, 100 direkt in den Berechnungsprozess zu schreiben. Wir planen auch, Benutzern die Möglichkeit zu geben, den Bereich der Summe anzugeben ! Sie müssen also 100 als Parameter an den Berechnungsprozess übergeben. In der Übersicht starten wir den Berechnungsprozess durch den Aufruf der RunWorkerAsync-Methode. Tatsächlich kann diese Methode einen Objekttypparameter akzeptieren. Dadurch können wir beliebige Daten an den Berechnungsprozess übergeben:

//别忘了设置滚动条。
this.progressBarSum.Maximum = 100;
_demoBGWorker.RunWorkerAsync(100);
//下面是更新后的 BGWorker_DoWork 方法:
private void BGWorker_DoWork(object sender, DoWorkEventArgs e)
{
  //在这里执行耗时的运算。
  int endNumber = 0;
  if(e.Argument != null)
  {
    endNumber = (int)e.Argument;
  }
  int sum = 0;
  for (int i = 0; i <= endNumber; i++)
  {
    sum += i;
  }
}
Der BGWorker_DoWork-Ereignishandler übergibt die Berechnungsinformationen, die wir erwarten, über das Argument

-Attribut des Parameters e.

Übertragen Sie die Nachricht an die Benutzeroberfläche

Da der Berechnungsprozess relativ lang ist, zeigen wir den aktuellen Fortschritt über den

Fortschrittsbalken an Ich hoffe auch, die Zwischenergebnisse der Berechnung in Echtzeit auf der Benutzeroberfläche anzuzeigen. Natürlich bietet BackgroundWorker auch für diesen Anwendungsfall eine gute Unterstützung. Es ermöglicht uns, während des Berechnungsprozesses Nachrichten an den UI-Thread zu senden. Schauen wir uns die spezifische Methode an:

_demoBGWorker.WorkerReportsProgress = true;
_demoBGWorker.ProgressChanged += BGWorker_ProgressChanged;
Setzen Sie zuerst die WorkerReportsProgress-Eigenschaft auf true und dann Legen Sie das ProgressChanged-Ereignis fest. Fügen Sie eine Verarbeitungsmethode hinzu:

private void BGWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
  //修改进度条的显示。
  this.progressBarSum.Value = e.ProgressPercentage;

  //如果有更多的信息需要传递,可以使用 e.UserState 传递一个自定义的类型。
  //这是一个 object 类型的对象,您可以通过它传递任何类型。
  //我们仅把当前 sum 的值通过 e.UserState 传回,并通过显示在窗口上。
  string message = e.UserState.ToString();
  this.labelSum.Text = message;
}
Fahren Sie mit der Aktualisierung der BGWorker_DoWork-Methode fort:

private void BGWorker_DoWork(object sender, DoWorkEventArgs e)
{
  BackgroundWorker bgWorker = sender as BackgroundWorker;
  int endNumber = 0;
  if(e.Argument != null)
  {
    endNumber = (int)e.Argument;
  }

  int sum = 0;
  for (int i = 0; i <= endNumber; i++)
  {
    sum += i;
    
    string message = "Current sum is: " + sum.ToString();
    //ReportProgress 方法把信息传递给 ProcessChanged 事件处理函数。
    //第一个参数类型为 int,表示执行进度。
    //如果有更多的信息需要传递,可以使用 ReportProgress 的第二个参数。
    //这里我们给第二个参数传进去一条消息。
    bgWorker.ReportProgress(i, message);
    Thread.Sleep(600);
  }
}
OK, jetzt können Sie die Aktualisierung des Fortschrittsbalkens und der Ausführungsinformationen sehen.

Vorgang abbrechen

Es ist ein grundlegendes Design, dem Benutzer zu erlauben, den aktuellen Vorgang während der Ausführung abzubrechen, und BackgroundWorker bietet natürlich gute Unterstützung:

_demoBGWorker.WorkerSupportsCancellation = true;
Wie das WorkerReportsProgress-Attribut müssen wir das WorkerSupportsCancellation-Attribut auf „true“ setzen, wenn wir Abbruchvorgänge unterstützen möchten. Und Sie müssen es auch in der BGWorker_DoWork-Methode unterstützen. Fügen Sie Code nach Thread.Sleep(600) in der for

-Schleife hinzu:

 bgWorker.ReportProgress(i, message);
Thread.Sleep(600);

//在操作的过程中需要检查用户是否取消了当前的操作。
if (bgWorker.CancellationPending == true)
{
  e.Cancel = true;
  break;
}
Wenn Sie auf die Schaltfläche „Abbrechen“

geklickt haben Wenn der Benutzer erkannt wird , beenden Sie einfach den aktuellen Berechnungsprozess . Der folgende Code wird aufgerufen, wenn Sie auf die Schaltfläche „Abbrechen“ klicken:

_demoBGWorker.CancelAsync();
Der Vorgang „Abbrechen“ wird jetzt unterstützt. Probieren Sie es jetzt aus!

Ausnahmebehandlung

Was tun, wenn während der Berechnung eine Ausnahme auftritt? Gibt es eine Möglichkeit zu wissen, dass der Berechnungsprozess beendet ist? Selbst wenn es normal endet, müssen wir natürlich immer noch die berechneten Ergebnisse erhalten.

_demoBGWorker.RunWorkerCompleted += BGWorker_RunWorkerCompleted;
private void BGWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
  //如果用户取消了当前操作就关闭窗口。
  if (e.Cancelled)
  {
    this.Close();
  }

  //计算已经结束,需要禁用取消按钮。
  this.btnCancel.Enabled = false;

  //计算过程中的异常会被抓住,在这里可以进行处理。
  if (e.Error != null)
  {
    Type errorType = e.Error.GetType();
    switch (errorType.Name)
    {
      case "ArgumentNullException":
      case "MyException":
        //do something.
        break;
      default:
        //do something.
        break;
    }
  }

  //计算结果信息:e.Result
  //use it do something.
}
Die Event-Handler-Funktion „RunWorkerCompleted“ wird aufgerufen, nachdem die Event-Handler-Funktion „DoWork“ zurückgekehrt ist. Dadurch können wir nach dem Vorgang einige Vorgänge ausführen, z. B. das Deaktivieren der Schaltfläche „Abbrechen“, die Ausnahmebehandlung, die Ergebnisanzeige usw.


Beachten Sie, dass Sie, wenn Sie e.Result erhalten möchten, das e.Result-Attribut in der BGWorker_DoWork-Methode festlegen müssen, wie zum Beispiel:

e.Result = sum;
Zusammenfassend ist das Die BackgroundWorker-Klasse verfügt über vollständige Funktionen, ist einfach zu verwenden und ein wirklich leistungsstarkes Tool für die Handhabung asynchroner zeitaufwändiger Vorgänge!

Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung der Verwendung von BackgroundWorker in C# (Bild). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn