2010-05-31 42 views
5

我想在System.Threading.Tasks命名空間中使用新的線程構造實現可取消的工作線程。 到目前爲止,我想出了這個實現:如何實現可取消的工作線程

public sealed class Scheduler 
{ 
    private CancellationTokenSource _cancellationTokenSource; 
    public System.Threading.Tasks.Task Worker { get; private set; } 

    public void Start() 
    { 
     _cancellationTokenSource = new CancellationTokenSource(); 

     Worker = System.Threading.Tasks.Task.Factory.StartNew(
      () => RunTasks(_cancellationTokenSource.Token), 
      _cancellationTokenSource.Token 
     ); 
    } 

    private static void RunTasks(CancellationToken cancellationToken) 
    { 
     while (!cancellationToken.IsCancellationRequested) 
     { 
      Thread.Sleep(1000); // simulate work 
     } 
    } 

    public void Stop() 
    { 
     try 
     { 
      _cancellationTokenSource.Cancel(); 
      Worker.Wait(_cancellationTokenSource.Token); 
     } 
     catch (OperationCanceledException) 
     { 
      // OperationCanceledException is expected when a Task is cancelled. 
     } 
    } 
} 

Stop()回到我期待Worker.StatusTaskStatus.Canceled
我的單元測試表明,在一定條件下Worker.Status仍然設置爲TaskStatus.Running

這是實現可取消的工作線程的正確方法嗎?

回答

5

我認爲這個問題是在您的來電

Worker.Wait(_cancellationTokenSource.Token); 

這是等待令牌將信號 - 這已經是,因爲你剛剛叫Cancel()。如果你改變這只是

Worker.Wait(); 

那麼我相信你會看到一個狀態RanToCompletion。你不會看到取消,因爲你的任務不是拋出OperationCanceledException。如果你改變你的RunTasks方法調用

cancellationToken.ThrowIfCancellationRequested() 

末,那麼你就需要捕捉的AggregateExceptionStop - 但你會在年底看到的Canceled的狀態。

至少,這是我的實驗顯示:)

+0

是的,這解決了問題。謝謝。 – 2010-06-01 08:04:17