У меня есть два фоновых работника в моем приложении, которые заполняют таблицу и отправляют сообщения журнала. Они передают эти данные с помощью «userState» метода ReportProgress.
Они подключены к основной нити через:C# Фоновый работник: исключение, когда Close() называется
msg_worker.DoWork += message_worker_task;
msg_worker.ProgressChanged += msg_worker_ProgressChanged;
msg_worker.RunWorkerCompleted += worker_completed;
data_worker.DoWork += data_worker_task;
data_worker.ProgressChanged += data_worker_ProgressChanged;
data_worker.RunWorkerCompleted += worker_completed;
Они синхронизированы с использованием двух EventWaitHandle элементов, что они, установленные в конце их DoWork задачи:
private void message_worker_task(object sender, DoWorkEventArgs e)
{
try
{
while(..){
// do work
bw.ReportProgress(10, new String("my message to append"));
}
}
finally
{
e.Result = 0;
msg_done.Set(); // EventWaitHandle
}
}
Прогресс изменил делегаты вставки данных/войдите в компоненты, видимые пользователю.
Теперь проблема в том, что при нажатии на кнопку Quit в моем UI, я на этих 2-х потоков, как это:
private void wait_threads()
{
int timeout = 30000;
Cursor.Current = Cursors.WaitCursor;
if (data_worker.IsBusy && !data_worker.CancellationPending)
{
data_worker.CancelAsync();
data_done.WaitOne(timeout);
}
if (msg_worker.IsBusy && !msg_worker.CancellationPending)
{
msg_worker.CancelAsync();
msg_done.WaitOne(timeout);
}
Cursor.Current = Cursors.Default;
}
Это, кажется, работает (я использую его в других местах код), но в этом случае «прекращения» у меня возникло исключение, говоря, что я попытался вставить данные в компонент журнала, который у меня есть. Этот компонент обрабатывается делегатом RunWorkerCompleted.
Код, который запускается на выполнение, когда Бросить нажата эта:
private void quit_Click(object sender, EventArgs e)
{
wait_threads(); // blocks until threads are finished
Close();
}
Я думаю, что я понял, что во время ожидания потоков завершения, они посылают последнее событие: RunWorkerCompleted. Проблема в том, что я вхожу в процесс Close() в моей форме, что означает, что форма не находится в правильном состоянии. Более того, если я проверить e.Cancelled
флаг в функции worker_completed
, я вижу это как ложь ...
Что я могу сделать, чтобы убедиться, что RunWorkerCompleted обрабатывается перед тем моя Close()
функция запускается на выполнение? (вернее, не обрабатывается вообще, потому что мы уходим).
Есть ли опечатка? waith_threads() вместо wait_threads()? – Guido
Да;) Я сократил код и пропустил это. – Gui13