2010-05-31 44 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