2010-10-06 2 views
0

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

У меня есть основная форма, которая запустит рабочий рабочий поток (рабочий). Рабочий поток выполнит цикл бесконечности While (! Stopping) и будет спать в конце каждого итерационного завершения глобальным объектом остановки (объект блокировки только для чтения). При правильной работе при нажатии кнопки «Стоп» рабочий стол остановится после текущей итерации.

Теперь, когда пользователь закрывает основную форму, он сначала устанавливает флаг «Стоп», чтобы рабочий поток завершил свое текущее задание. После этого основная форма закроется. Кажется достаточно простым, но я не мог заставить его работать.

Я попробовал либо worker.Join(), либо test woker.IsAlive в цикле while, но оба случая заблокируют приложение (основная форма) через несколько секунд по какой-то причине?

Ниже мой код в обработчик события Form_Closing (не работает):

   // Tell the thread to stop the file 
       Stop(); 
       Logger.Info("Stopping the thread by Close the application"); 
       //Not working as well      
       //worker.Join(); 
       while (worker.IsAlive) 
       { 
        Thread.Sleep(5000); 
        Logger.Info("After sleep for 5 seconds"); 
       } 
       Logger.Info("worker thread stopped"); 

Одно интересное в том, что рабочий поток кажется, всегда пишет журнал событий до конца каждой итерации цикла, то остальные запись в журнале будет основным событием формы внутри цикла while (worker.IsAlive).

ответ

2

Регистрация будет всегда ждать в потоке, используя его в потоке пользовательского интерфейса, сделает приложение заблокированным. IsAlive не блокирует ничего в потоке GUI, это ваш Thread.Sleep.

сделать somethnig как это вместо:

while (worker.IsAlive) 
{ 
    Thread.sleep(50); 
    Application.DoEvents(); 
} 
+0

Спасибо, это решение работает хорошо. –

0

Вы создаете тупик, который как-то ставит точку прерывания всюду по вашему запросу и освобождает объект блокировки. Также вы можете использовать класс system.threading.monitor, чтобы проверить, имеется ли блокировка, а не создание взаимоблокировки. Узнайте о окне потоков в VS.

+0

К сожалению, это наш первый проект .NET 4.0, и в результате я в настоящее время работаю с использованием VS2010 Express. Не похоже, что у него есть окно потока для отладки. –

0

Имейте в виде, что любой код, который вы используете, что вызывает поток пользовательского интерфейса приостановить свою нормальную обязанность насосных сообщений будет проявляться как зависание пользователя. Другими словами, не вызывать любой метод, который может блокировать включая Thread.Join, Thread.Sleep, WaitHandle.WaitOne и т.д.

Так как вы хотите, чтобы работник прекратить после закрытия формы, то я предлагаю дать форму, близкую после того, как сигнал остановки был отправлен к рабочей нити. Добавьте вызов Thread.Join в точку входа приложения после вызова Application.Run. Поскольку вы завершаете приложение, можно безопасно позвонить Thread.Abort, если поток не отвечает своевременно. Вот пример кода.

public void Main(string[] args) 
{ 
    var form = new YourForm(); 
    Application.Run(form); 
    if (!form.WorkerThread.Join(TIME_TO_WAIT)) 
    { 
    form.WorkerThread.Abort(); 
    } 
} 
+0

Спасибо Брайан Гидеон, я проверил ваше решение, но моя основная форма закроется мгновенно. Проблема в том, что я действительно не понимаю ваше решение, не уверен, что я правильно его осуществил. –

+0

В основном я сейчас просто вызываю Stop(), чтобы установить флаг остановки для рабочего потока в закрывающем событии формы. И я думаю, что в этот момент моя основная форма будет закрыта, и выполнение вернет program.cs в строку: if (! Form.WorkerThread.Присоединиться (TIME_TO_WAIT)), но поскольку основная форма закрыта в этой точке и кажется, что функция Logger не работает с этой точки, как узнать, что произошло с этой точки? –

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