Waiting the main thread to stop until a task is processed by an async thread
Lets say we have a following program where in its Start method, it delegates some long running task to another thread. When the Stop method is called, i开发者_运维问答 need to make sure that worker thread completes executing the current task and does not leave it in the middle of it. If it has already completed the task and is in sleep state, then it can stop immidiately.
Please guide me on how should I do it.
static int itemsProcessed = 0;
static Thread worker;
static void Start()
{
var ts = new ThreadStart(Run);
worker = new Thread(ts);
worker.Start();
}
static void Stop()
{
//wait until the 'worker' completes processing the current item.
Console.WriteLine("{0} Items Processed", itemsProcessed);
}
static void Run(object state)
{
while (true)
{
ALongRunningTask();
itemsProcessed++;
Thread.Sleep(1000);
}
}
One way to do this is to use a volatile variable to communicate betweej the two threads. To do this, create a "volatile bool isRunning;". In Start set the value to true, then in Run chage your while loop to "while (isRunning)". In stop, set isRunning equal to false and then call worker.Join(). This will cause your run method to exit when it finishes processing the current item, and Join will wait until the thread exits.
The last thing you need to do is to access itemsProcessed in a thread-safe way. In the current code there is no way to know if Stop sees the most up to date value of itemsProcessed since it was changed from another thread. One option would be to create a lock for itemsProcessed and hold the lock inside of Run, and acquire the lock before the WriteLine statement in Stop.
Assuming you always want the long running task thread as a whole to finish, you could just wait till the thread is done by calling Thread.Join();
If you want to finish work in your thread gracefully you must do some sort of message passing, in the most simple case it could be just a boolean - in your case there seems to be just one thread, so it can be a static variable (simplifying here as much as possible)
static volatile bool processing = true;
static void Stop()
{
processing = false;
//wait until the 'worker' completes processing the current item.
worker.Join();
Console.WriteLine("{0} Items Processed", itemsProcessed);
}
static void Run(object state)
{
while (proccessing)
{
ALongRunningTask();
itemsProcessed++;
}
}
精彩评论