2010-12-03 84 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