この記事では主に C#BackgroundWorker の使い方を詳しく紹介していますので、参考になれば幸いです。エディターに従って見てみましょう
C# プログラムでは、CPU に負荷がかかり、長時間かかる操作が UI スレッド上で直接実行されると、UI が応答しなくなるという問題が発生することがあります。この種の問題を解決する主な方法は、マルチスレッドを使用し、バックグラウンド スレッドを開始し、このバックグラウンド スレッドでコンピューティング操作を完了することです。ただし、ネイティブ インターフェイスのスレッド操作は少し難しく、スレッド間の通信をさらに完了させたい場合はさらに難しくなります。
幸いなことに、.NET クラス ライブラリ は、この種の問題をよりエレガントに解決できる BackgroundWorker と呼ばれるクラスを提供します。 BackgroundWorker クラスは比較的簡単に使用できますが、注意が必要な詳細がいくつかあります。以下では、デモ プログラムを通じてその主な使用方法を紹介します。デモでは、1 から 100 までの累積合計を計算します。デモでは、各計算は 600 ミリ秒間スリープします。 デモの UI は次のとおりです。時間のかかる操作を DoWork
イベント処理関数
に追加し、その RunWorkerAsync メソッドを呼び出すだけです。rreeちょっとシンプルすぎませんか?それでは、次の質問について考えてみましょう:
操作プロセスにパラメータを渡したい場合はどうすればよいでしょうか?計算プロセス中にリアルタイムの情報を UI に表示したい場合はどうすればよいですか?
進行中の操作をキャンセルしたい場合はどうすればよいですか?操作中に例外が発生した場合はどうすればよいですか?
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; } }
属性
を介して、期待される計算情報を渡します。UI にメッセージを渡します
計算プロセスは比較的長いため、現在の進行状況を にメッセージを送信できるようになります。具体的なメソッドを見てみましょう://别忘了设置滚动条。 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; } }
_demoBGWorker.WorkerReportsProgress = true; _demoBGWorker.ProgressChanged += BGWorker_ProgressChanged;
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; }
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); } }
ループ
の Thread.Sleep(600) の後にコードを追加します:_demoBGWorker.WorkerSupportsCancellation = true;
現在の計算プロセスを
終了します。 。以下は、キャンセル ボタンをクリックしたときに呼び出されるコードです:bgWorker.ReportProgress(i, message); Thread.Sleep(600); //在操作的过程中需要检查用户是否取消了当前的操作。 if (bgWorker.CancellationPending == true) { e.Cancel = true; break; }
_demoBGWorker.CancelAsync();
e.Result を取得したい場合は、BGWorker_DoWork メソッドで次のように e.Result 属性を設定する必要があることに注意してください。 _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.
}
以上がC#でのBackgroundWorkerの使い方を詳しく解説(画像)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。