Изящное завершение потока

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

MyWorker worker = new MyWorker();
MainForm mainForm = new MainForm();

// Subscribe form to log event so log data gets displayed
worker.Log += mainForm.Log;

// Start the worker thread's MainLoop
new Thread(new ThreadStart(worker.MainLoop)).Start();

// Show the form (blocking)
Application.Run(mainForm);

// If we end up here, the form has been closed and the worker has to stop running            
worker.Running = false;

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

public class MyWorker
{
    public String Running { get; set; }

    public MyWorker()
    {
        Running = true;
    }

    public void MainLoop()
    {

        while (Running)
        {

            DoExtensiveWork1();
            if (!Running) return;

            DoExtensiveWork2();
            if (!Running) return;

            DoExtensiveWork3();
            if (!Running) return;

            DoExtensiveWork4();
            if (!Running) return;

            DoExtensiveWork5();         
            if (!Running) return;

            // We have to wait fifteen minutes (900 seconds) 
            // before another "run" can be processed
            for (int i = 0; i < 900; i++)
            {
                Thread.Sleep(1000);
                if (!Running) return;
            }
        }
    }
}

Как видите, я хочу, чтобы поток мог останавливаться при переключении между последовательными рабочими операциями, но не во время операции. Когда операция ( DoExtensiveWorkN ) завершена, ее статус и результаты сохраняются на диске или в базе данных, поэтому завершение операции во время выполнения операции (например, с помощью Thread.Abort ) не вариант.

Однако я считаю этот код, который я только что написал, отталкивающим, особенно "цикл ожидания", который 900 раз засыпает на одну секунду, чтобы предотвратить бездействие потока в течение 15 минут до обнаружения Выполняется был установлен на false .

Я бы предпочел создать какое-то событие, чтобы остановить основной цикл, как только он завершит работу.

Может ли кто-нибудь указать мне в правильном направлении, как это сделать, или, если требуется полная перезапись из-за того, что я совершенно неправильно понял многопоточность, покажите мне где-нибудь, где объясняются эти принципы?

6
задан CodeCaster 20 October 2011 в 10:09
поделиться