BackgroundWorker を使用して定期的に ping 操作を実行するツールに取り組んでいます。BackgroundWorker ProgressChanged イベントで問題が発生しています。ProgressChanged イベントのコードは次のとおりです。
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
ProgressUpdated update = (ProgressUpdated)e.UserState;
if (sender.ToString() == "System.ComponentModel.BackgroundWorker")
{
toolStripStatusLabel1.Text = update.GeneralStatus;
toolStripProgressBar1.Value = update.ProgressStatus;
toolStripStatusLabel2.Text = update.SpecificStatus;
}
else
{
toolStripStatusLabel1.Text = update.GeneralStatus;
toolStripProgressBar2.Value = update.ProgressStatus;
toolStripStatusLabel3.Text = update.SpecificStatus;
}
}
ProgressChanged イベントは、最初の値を更新する BackgroundWork と、ping が終了したときに pingcompletedcallback イベントの両方で呼び出されます。ProgressChanged イベントが PingCompletedCallback イベントから実行される場合にのみ、クロス スレッドの問題が発生します。2 番目の進行状況バーを更新しようとすると、エラーがスローされます。
一方の通話で発生しているのに、もう一方の通話では発生していない理由がわかりません。
PingCompletedCallBack は BackgroundWorker スレッドで発生していますか?それがクロススレッドの問題を引き起こしている理由ですか?
もしそうなら、バックグラウンドワーカーではなくUIスレッドで処理されるようにイベントを発生させるにはどうすればよいですか?
編集:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
// creates ping and sends it async
ProgressUpdated args = new ProgressUpdated(string1, int1, string 2);
worker.ReportProgress(0,args);
// rest of thread for cleanup when cancellation is called
}
private void PingCompletedCallback(object sender, PingCompletedEventArgs e)
{
// handle the ping response
ProgressUpdated update = new ProgressUpdated(string1, int1, string2);
ProgressChangedEventArgs changed = new ProgressChangedEventArgs(1,update);
backgroundWorker1_ProgressChanged(this, changed);
// handle other types of responses
}
イベントの使用は、スレッドの分離を可能にすることだと思いました。別名ワーカー スレッドは、UI スレッドがリッスンしているイベントを発生させ、発生したイベントは UI スレッドで処理されます。
私の理解が間違っていたので、PingCompletedCallBack はバックグラウンド ワーカーの ReportProgress メソッドにアクセスできますか?
次に、PingCompletedCallback で次のように変更できます。
ProgressChangedEventArgs changed = new ProgressChangedEventArgs(1,update);
backgroundWorker1_ProgressChanged(this, changed);
に:
backgroundWorker1.ReportProgress(1, update);
または、他の方法で変更する必要がありますか?
誰の助けにも感謝します。
編集2:
変更された ProgrssChanged イベント
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
ProgressUpdated update = (ProgressUpdated)e.UserState;
toolStripStatusLabel1.Text = update.GeneralStatus;
toolStripProgressBar1.Value = update.ProgressStatus;
toolStripStatusLabel2.Text = update.SpecificStatus;
}
次に、2 つ目の更新イベントを作成しました
private void PingUpdate (object sender, ProgressUpdated e)
{
toolStripStatusLabel1.Text = e.GeneralStatus;
toolStripProgressBar2.Value = e.ProgressStatus;
toolStripStatusLable3.Text = e.SepcificStatus;
}
私が残した唯一のことは、UI スレッドで実行されるような方法で PingCompletedCallback から新しいイベントを呼び出すことです。これは Invoke ステートメントが使用される場所ですか、それとも新しいイベントで Invoke を使用する必要がありますか?