一連のデータ集約型タスクを起動する単純なアプリがあります。私は WinForms の経験があまりないので、インターフェイスをロックせずにこれを行う最善の方法を考えていました。backgroundWorker を再利用できますか、またはこれを行う別の方法はありますか?
ありがとう
一連のデータ集約型タスクを起動する単純なアプリがあります。私は WinForms の経験があまりないので、インターフェイスをロックせずにこれを行う最善の方法を考えていました。backgroundWorker を再利用できますか、またはこれを行う別の方法はありますか?
ありがとう
BackgroundWorker
通知の同期も含むスレッドです。たとえば、スキャンが完了したときに UI を更新したい場合、通常Thread
のユーザーは UI オブジェクトにアクセスできません (これを実行できるのは UI スレッドだけです)。そのため、BackgroundWorker
操作が完了したときに UI スレッドで実行される Completed イベント ハンドラーを提供します。
詳細については、次を参照してください:チュートリアル: BackgroundWorker コンポーネントを使用したマルチスレッド (MSDN)
そして簡単なサンプルコード:
var worker = new System.ComponentModel.BackgroundWorker();
worker.DoWork += (sender,e) => Thread.Sleep(60000);
worker.RunWorkerCompleted += (sender,e) => MessageBox.Show("Hello there!");
worker.RunWorkerAsync();
backgroundWorker
使用できます。
その利点-プログレスバーを更新し、UIコントロールを操作できるようになります。(WorkerReportsProgress
)
また、キャンセルメカニズムがあります。(WorkerSupportsCancellation
)
このような要件には、BackgroundWorkerを使用できます。以下はそのサンプルですupdates a label status based on percentage task [long running] completion
。また、いくつかの値を設定し、その値がProgressChanged
ハンドラーを介してUIに戻されるサンプルビジネスクラスがあります。DoWork
長時間実行されるタスクロジックを作成する場所です。コピー-Winformsアプリにラベルとbackgroundworkerコンポーネントを追加した後、以下のコードを貼り付けて、試してみてください。さまざまなハンドラー[RunWorkerCompleted, ProgressChanged, DoWork]
でデバッグし、InitWorker
メソッドを確認できます。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;
}
}
}
バックグラウンドワーカーは、最初に良い選択です
詳細については、こちらを ご覧くださいhttp://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx