假设我们有一个以下程序,在其Start方法中,它将一些长时间运行的任务委托给另一个线程。当调用Stop方法时,我需要确保工作线程完成执行当前任务并且不将它留在中间。如果它已经完成任务并处于睡眠状态,那么它可以立即停止。
请指导我如何做。
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);
}
}
答案 0 :(得分:1)
假设您总是希望将长时间运行的任务线程作为一个整体来完成,您可以通过调用Thread.Join();
等待线程完成。如果你想优雅地完成你的线程中的工作,你必须做一些消息传递,在最简单的情况下它可能只是一个布尔值 - 在你的情况下似乎只有一个线程,所以它可以是一个静态变量(尽可能简化)
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++;
}
}
答案 1 :(得分:1)
执行此操作的一种方法是使用volatile变量在两个线程之间进行通信。为此,创建一个“volatile bool isRunning;”。在Start中将值设置为true,然后在Run chage中将while循环设置为“while(isRunning)”。在stop中,将isRunning设置为false,然后调用worker.Join()。这将导致run方法在完成处理当前项时退出,Join将等待线程退出。
您需要做的最后一件事是以线程安全的方式访问itemsProcessed。在当前代码中,无法知道Stop是否看到itemsProcessed的最新值,因为它已从另一个线程更改。一种选择是为itemsProcessed创建一个锁并在Run中保持锁,并在Stop中的WriteLine语句之前获取锁。