我一直在研究一個使用BackgroundWorker以定期間隔執行ping操作的工具。我遇到了BackgroundWorker ProgressChanged事件。爲ProgressChanged事件的代碼如下:使用BackgroundWorker和statusstrip更新的CrossThreading問題
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從pingcompletedcallback事件調用時,平結束。當ProgressChanged事件從PingCompletedCallback事件運行時,我只遇到跨線程問題。它在更新第二個進度條時拋出錯誤。
我似乎無法弄清楚爲什麼它發生的其中一個電話,而不是其他。
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是否可以訪問BackgroundWorker的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;
}
然後,我創建了第二個更新事件
private void PingUpdate (object sender, ProgressUpdated e)
{
toolStripStatusLabel1.Text = e.GeneralStatus;
toolStripProgressBar2.Value = e.ProgressStatus;
toolStripStatusLable3.Text = e.SepcificStatus;
}
我留下的唯一的事情就是打電話從PingCompletedCallback新事件它在UI線程上執行的方式。這是在哪裏使用Invoke語句,還是應該在新事件中使用Invokes?
附註:最好是說 「發件人是BackgroundWorker的」 比sender.ToString()。由於ProgressChanged在UI線程上執行,因此不需要Invoke。 – 2012-03-08 09:09:23
您不應該在backgroundWorker1_ProgressChanged方法中使用任何類型的調用。使用ReportProgress報告進度,因爲這正是這些後臺工作人員的目標;使後臺任務與GUI同步。不要調用backgroundWorker1_ProgressChanged(this,changed),因爲它將從工作線程調用。 – Philippe 2012-03-08 17:26:10