2009-08-14 2 views
0

Правильно, мое приложение время от времени запускает фоновый поток, который делает некоторые вещи.Основная нить, ожидающая на фоне потоков, которые обновляют интерфейс

Поскольку он выполняет свои функции, он также обновляет индикатор выполнения в главном окне. Он делает это, вызывая Invoke, чтобы получить основной поток для обновления интерфейса.

Когда пользователь закрывает приложение, я хочу дождаться завершения всех фоновых потоков перед закрытием формы. В форме закрытия события у меня есть что-то вроде

  while (this._Queue.Count > 0) 
      Application.DoEvents(); 

Но это не работает!

Фоновая нить застревает в вызове Invoke. Основной поток продолжает вращаться вокруг вызова его DoEvents, который, как мне казалось, нужно будет делать, чтобы поднять и обработать его вызовы. Но это не делает это ...

Почему бы и нет!?!

+1

Привет, , где вы поместите этот код в главном событии формы закрытия? С наилучшими пожеланиями, Iordan – IordanTanev

+0

Да, это событие Main form form_closing. –

ответ

0

Правильно, я разобрался с проблемой, взяв ее под другим углом. Больше не нужно ждать, пока потоки закончатся ...

Я только что добавил переменную bool KillOnThreadFinish в рабочий поток.

Затем в форме закрытия основной формы я проверяю, работает ли поток. Если я установлен KillOnThreadFinish = true, я устанавливаю e.cancel = true (чтобы предотвратить закрытие формы в этой точке), и я установил MainForm.Enabled = false (чтобы не допустить закрытия пользователем формы).

Затем, когда поток заканчивает работу, он проверяет KillOnThreadFinish, и если True вызывает приложение Application.Exit() и приложение завершает работу.

Кажется работать красиво!

(Спасибо за то, ребята. :-))

0

Предлагаю ввести код в событии «Закрытие» формы. Кроме того, вы можете попробовать добавить Thread.Sleep(100) после Application.DoEvents().

Кроме того, я бы создать ManualResetEvent называется threadDone или аналогичный, который устанавливается при запуске (передать true конструктору события), получает сброс до начала резьбы и устанавливается нить указала, что она делается работает.

Тогда вы могли бы переписать петлю следующим образом:

while (!threadDone.WaitOne(100, true)) 
{ 
    Application.DoEvents(); 
    Thread.Sleep(100); 
} 

Это может помочь - но я на самом деле не пробовал это прямо сейчас. Обычно я использую событие сброса, чтобы проверить, можно ли закрыть приложение или форму. Если поток не выполнен, я показываю сообщение пользователю.

1

BackgroundWorker обеспечивает удобный способ запуска фоновых потоков, позволяя легко сообщать о прогрессе с помощью событий .NET. Вы подключили бы обновление ProgressBar UI к обработчику событий ProgressChanged, и завершение будет сообщено вам через RunWorkerCompleted. Если у вас есть только один фоновый поток, это намного проще, чем перенос собственного кода обработки потоков. Вот статья MSDN:

http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx

Если вы застряли с помощью регулярных потоков, то я бы рассмотреть возможность использования Регистрация ждать нити, чтобы закончить. Это позволяет обрабатывать обычные сообщения и экономит ваш опрос в узком цикле. Там больше информации здесь:

http://msdn.microsoft.com/en-us/library/95hbf2ta.aspx

Кроме того, существуют перегрузки, которые принимают параметр тайм-аута (либо в Int32 для миллисекунд или объект TimeSpan). Если поток не завершился по истечении этого времени, генерируется исключение. Это помогает улавливать потоки, которые застревают во время остановки. Подробнее здесь:

http://msdn.microsoft.com/en-us/library/6b1kkss0.aspx

Я надеюсь, что это помогает.

+0

Присоединиться, похоже, не работает, он все равно попадает в тупик с основной нитью, застрявшей на Join, а рабочий поток застрял в Invoke. –

0

Основная нить не должна ждать какой-либо другой темы, а другая нить должна сигнализировать о завершении ее работы.

В вашем случае я бы просто использовал метод Control.Invoke или Control.BeginInvoke другой темы для обновления интерфейса.

+0

Я, его не работает .. –

+0

Основной поток НЕ должен быть заблокирован ожиданием чего-то, он ничего не должен делать. В то же время ДРУГОЙ поток завершает работу и уведомляет основной поток. –

Смежные вопросы