BackgroundWorkerは、リストボックスにアイテムを追加するときにC#で問題を引き起こしますか?
-
06-07-2019 - |
質問
リストボックスがあり、マージするために最低2つのファイルを指定する必要があります。 マージボタンをクリックすると、マージが完了します。プログレスバーが起動し、ファイルがマージされたというメッセージボックスが表示されます。バックグラウンドワーカーを使用してプログレスバーを実行しています。
問題は、2つのファイルでマージが完了したときに、もう1つのファイルを追加し、マージボタンをクリックして、マージが完了したというメッセージが表示され、メッセージボックスで[OK]をクリックし、再度、メッセージボックスがこのメッセージボックスは、リストボックスにファイルを追加した回数だけ表示され続けます。
たとえば、2ファイルの場合、メッセージを追加すると1ce denが表示され、さらに1個のファイルメッセージが表示されます2ice、リストボックスにさらに1個のメッセージが表示されます3ic。
デバッガーを使用して追跡すると、リストボックスにファイルを追加するたびに、バックグラウンドワーカーのRuncompletedイベントがその回数呼び出されることに気付きました。マージボタンクリックイベントのコードは次のとおりです。
Worker.DoWork += new DoWorkEventHandler(Worker_DoWork);
Worker.RunWorkerCompleted +=
new RunWorkerCompletedEventHandler(Worker_RunWorkerCompleted);
Worker.WorkerSupportsCancellation = true;
if (!Worker.IsBusy)
Worker.RunWorkerAsync();
else
MessageBox.Show("Cannot run background worker twice ");
if (Worker.IsBusy)
{
progress = new ProgressDialogDTB();
progress.FormClosing +=
new FormClosingEventHandler(ProgressDialog_FormClosing);
progress.ShowDialog(this);
}
while (Worker.IsBusy)
{
Application.DoEvents();
}
//For Background Worker completed Event...
private void Worker_RunWorkerCompleted(object sender,
AsyncCompletedEventArgs e)
{
if (progress != null)
{
progress.Close();
progress = null;
}
if ( e.Cancelled )
MessageBox.Show(" Progress was cancelled ");
if (e.Error == null)
if (!e.Cancelled)
MessageBox.Show("Files has been merged ");
if (e.Error != null)
MessageBox.Show(e.Error.Message);
}//Worker_RunWorkerCompleted
どこで間違っているのかわかりません。 助けてください...ありがとう...
解決
Mergeボタンをクリックするたびに、新しいデリゲートを登録していると思います。次のコードの場合:
Worker.DoWork += new System.ComponentModel.DoWorkEventHandler(Worker_DoWork);
Worker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(Worker_RunWorkerCompleted);
は、マージボタンのクリックイベントハンドラーにあり、フォーム初期化メソッドに移動することを検討してください。デリゲートを登録する必要があるのは一度だけです。次回に新しいものを追加すると、2回目のMergeクリックで2回、3回目のクリックで3回、というように実行されます。
他のヒント
ワーカーがモジュールレベルの変数であり、ボタンがクリックされるたびにその呼び出しリストに追加する場合、そのメソッドは毎回呼び出されます。
3回クリックすると、このコード Worker.RunWorkerCompleted + =
new RunWorkerCompletedEventHandler(Worker_RunWorkerCompleted);
は3回実行され、3回呼び出されます。
ワーカーオブジェクトをインスタンス化するときに、Completedハンドラーを1回設定します。
ああ!それにBeatられた!