Я работал над инструментом, который использует BackgroundWorker для выполнения операции проверки связи с регулярным интервалом. Я столкнулся с проблемой с событием 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, где оно обновляет первые значения, так и из события pingcompletedcallback после завершения проверки связи. Я сталкиваюсь с проблемой перекрестного потока, только когда событие ProgressChanged запускается из события PingCompletedCallback. Выдает ошибку при обновлении второго индикатора выполнения.
Не могу понять, почему это происходит для одного из вызовов, а не для другого.
Происходит ли PingCompletedCallBack в потоке BackgroundWorker, и поэтому он вызывает проблемы с многопоточностью?
Если это так, как мне вызвать событие, чтобы оно обрабатывалось в потоке пользовательского интерфейса, а не в фоновом режиме?
Edit:
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
}
Я думал, что использование событий было для разделения потоков. Рабочий поток Aka вызывает событие, которое ожидает поток пользовательского интерфейса, а затем вызванное событие обрабатывается в потоке пользовательского интерфейса.
Поскольку мое понимание неверно, будет ли 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;
}
Затем я создал второе событие обновления
private void PingUpdate (object sender, ProgressUpdated e)
{
toolStripStatusLabel1.Text = e.GeneralStatus;
toolStripProgressBar2.Value = e.ProgressStatus;
toolStripStatusLable3.Text = e.SepcificStatus;
}
Единственное, что мне осталось, это вызвать новое событие из PingCompletedCallback таким образом, чтобы оно выполнялось в потоке пользовательского интерфейса. В этом месте будет использоваться оператор Invoke или должны использоваться вызовы в новом событии?