2010-12-03 91 views
1

假设我们有一个下面的程序,在其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); 
     } 
    } 

回答

1

一种方法是使用volatile变量在两个线程之间进行通信。为此,请创建一个“volatile bool isRunning;”。在开始设置值为true,然后在运行chage你的while循环到“while(isRunning)”。在停止中,将isRunning设置为false,然后调用worker.Join()。这将导致您的run方法在完成当前项目的处理时退出,并且Join将等待直到线程退出。

您需要做的最后一件事是以线程安全的方式访问itemsProcessed。在当前代码中,无法知道Stop是否从其他线程更改后看到itemsProcessed的最新值。一种选择是为itemsProcessed创建一个锁并将锁保持在Run中,并在Stop中的WriteLine语句之前获取锁。

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++; 
    } 
} 
+0

这需要处理为易失性,否则其他线程可能永远不会注意到值被更改。您也可以使用worker.Join方法代替睡眠循环。 – 2010-12-03 05:06:38