In an application I’m developing, I have a main form that simply sits there and displays log data, and a worker thread that autonomously does the work in a loop.
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;
As you can see, whenever the form is closed, the worker thread should be stopped. The worker looks like this:
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;
}
}
}
}
As you can see, I want the thread to be able to stop when switching between successive work operations, but not when within an operation. When an operation (DoExtensiveWorkN) has finished, its status and results are persisted do disk or database, so quitting while an operation is in progress (by, for example, Thread.Abort) is not an option.
However, I find this code I’ve just written repulsive to look at, especially the “wait loop” which sleeps for one second 900 times, to prevent the thread from idling for 15 minutes before detecting Running has been set to false.
I’d rather be able to throw some kind of event to stop the main loop as soon as it’s finished a piece of work.
Can anyone point me in the right direction how to do this, or if a total rewrite is required because I totally misunderstood threading, show me somewhere where those principles are explained?
You can tidy up both the running of the individual tasks and the 15 min wait loop considerably.
I’d suggest perhaps using something like this:
Then to stop the process at the next appropriate point: