1. ホーム
  2. c#

BackgroundWorkerの正しい停止方法

2023-08-19 12:32:43

質問



私は2つのコンボボックスがあるフォームを持っています。そして私は満たしたい combobox2.DataSource に基づいて combobox1.Textcombobox2.Text (で入力が完了したと仮定します)。 combobox1 への入力が完了し combobox2 ). そこで、私はイベントハンドラで combobox2 をこのようにします。

private void combobox2_TextChanged(object sender, EventArgs e)
{
    if (cmbDataSourceExtractor.IsBusy)
       cmbDataSourceExtractor.CancelAsync();

    var filledComboboxValues = new FilledComboboxValues{ V1 = combobox1.Text,
       V2 = combobox2.Text};
    cmbDataSourceExtractor.RunWorkerAsync(filledComboboxValues );
}

データソースの構築は時間がかかるので(データベースへのリクエストを作成して実行する)、BackgroundWorkerを使って別のプロセスで実行したほうがいいと判断しました。そこで、cmbDataSourceExtractorが作業を完了していないときに、ユーザーがもう一つシンボルをタイプするシナリオがある。この場合、私は次の行で例外を取得します。

cmbDataSourceExtractor.RunWorkerAsync(filledComboboxValues ); は、BackgroundWorkerがビジー状態であり、同時に複数のアクションを実行できないことを表しています。

この例外を取り除くにはどうすればよいですか。

事前にありがとうございます!

どのように解決するのですか?

CancelAsync は実際にスレッドを中止させたりはしません。Worker スレッドに対して、作業をキャンセルするように BackgroundWorker.CancellationPending . バックグラウンドで実行されている DoWork デリゲートは定期的にこのプロパティをチェックし、キャンセル自体を処理する必要があります。

厄介なのは、あなたのDoWorkデリゲートはおそらくブロッキングしているということです。つまり、あなたがDataSourceに対して行う作業は、他の何か(CancellationPendingのチェックなど)を行う前に完了しなければならないということです。実際の作業を別の非同期デリゲートに移す必要があるかもしれません(あるいは、よりよい方法として、作業を ThreadPool に送信する)、この内部ワーカー スレッドが待機状態をトリガーするか、CancellationPending を検出するまで、メイン ワーカー スレッドにポーリングさせる必要があるかもしれません。

http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.cancelasync.aspx

http://www.codeproject.com/KB/cpp/BackgroundWorker_Threads.aspx