2010-05-31 25 views
5

Tôi đang cố gắng triển khai một chuỗi công nhân có thể hủy bằng cách sử dụng các cấu trúc luồng mới trong không gian tên System.Threading.Tasks. Cho đến nay tôi đã đã đưa ra thực hiện điều này:Cách thực hiện chủ đề công nhân có thể hủy

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. 
     } 
    } 
} 

Khi Stop() lợi nhuận Tôi hy vọng Worker.StatusTaskStatus.Canceled.
Kiểm tra đơn vị của tôi đã cho thấy rằng trong các điều kiện nhất định Worker.Status vẫn được đặt thành TaskStatus.Running.

Đây có phải là cách chính xác để triển khai chuỗi công việc có thể hủy không?

Trả lời

5

Tôi tin rằng vấn đề là trong lệnh gọi

Worker.Wait(_cancellationTokenSource.Token); 

Đó là chờ đợi cho thẻ được hiệu - mà nó đã là, bởi vì bạn vừa gọi Cancel(). Nếu bạn thay đổi điều đó thành chỉ

Worker.Wait(); 

thì tôi tin bạn sẽ thấy trạng thái RanToCompletion. Bạn sẽ không thấy Bị hủy vì công việc của bạn không phải là ném OperationCanceledException. Nếu bạn thay đổi RunTasks phương pháp của bạn để gọi

cancellationToken.ThrowIfCancellationRequested() 

ở cuối, sau đó bạn sẽ cần phải bắt một AggregateException trong Stop - nhưng sau đó bạn sẽ thấy tình trạng Canceled ở cuối.

Ít nhất, đó là những gì thử nghiệm của tôi hiển thị :)

+0

Có, đã khắc phục sự cố. Cảm ơn. –

Các vấn đề liên quan