2011-11-16 33 views
8

Cho phép nói rằng tôi có bộ xử lý là công việc của người đó là lưu tệp vào đĩa. Điều này đang chạy dưới dạng Task trong khi quan sát BlockingCollection<T> để xử lý tệp.Thực tiễn hủy bỏ tác vụ tốt nhất

Khi tác vụ bị hủy và vẫn còn các tệp sẽ được lưu vào đĩa, bạn nên làm như thế nào? Nó sẽ thuận tiện để cho phép tác vụ ngay trước khi thoát nhanh chóng ghi các tệp còn lại vào đĩa mặc dù tôi không chắc liệu điều này có mâu thuẫn với triết lý hủy một tác vụ hay không (vì việc hủy bỏ sẽ diễn ra nhanh nhất có thể) .

Tùy chọn khác có quy trình thứ hai sau khi hủy tác vụ của người đó là ghi các tệp còn lại vào đĩa.

Mã dụ:

class FileProcessor 
{ 
    private readonly BlockingCollection<Stream> input; 

    public FileProcessor(BlockingCollection<Stream> input) 
    { 
     _input = input; 
    } 

    public Task Run(CancellationToken cancellationToken, 
     BlockingCollection<Stream> input) 
    { 
     return Task.Factory.StartNew(() => 
     { 
      foreach (Stream stream in 
         input.GetConsumingEnumerable(cancellationToken)) 
      { 
       WriteToDisk(stream); 
      } 

      // Should I call WriteRemaining here or should I have 
        // a process running after this task exited which 
        // will call WriteRemaining 
      WriteRemaining(); 
     }); 
    } 

    public void WriteRemaining() 
    { 
     foreach (Stream stream in input)  
     { 
      WriteToDisk(stream); 
     } 
    } 
} 

Tôi biết đây là một chút của một câu hỏi mở, các ứng dụng/yêu cầu/lượng các file cần viết cũng đóng một vai trò nhưng tôi tìm kiếm các hướng dẫn chung/tốt nhất thực hành ở đây.

+0

Tôi không nghĩ bạn thực sự muốn "Hủy" trong trường hợp này, tôi nghĩ bạn chỉ muốn dừng quá trình xử lý mà bạn có thể dễ dàng thực hiện với một semaphore đơn giản về bất kỳ khởi đầu mới nào. Để có nghĩa là "Hủy bỏ" ngụ ý dừng ngay lập tức cho một cái gì đó khác, nếu bạn muốn một "Stop" an toàn thì bạn có thể thực hiện điều đó bên ngoài các công cụ hủy có khả năng. Nhưng tôi không chắc liệu đó có phải là cách thực hành tốt nhất ... –

+0

không nên hoàn thành phần còn lại của bài viết trên người gọi hủy không? IMO WriteRemaining phải ở trong phương thức Register của đối tượng CancellationToken –

+0

Không có nghĩa vụ hợp đồng cho Hủy bỏ để chấm dứt nhanh chóng hoặc thậm chí gây ra hủy bỏ ở tất cả. Nếu quá trình của bạn không hỗ trợ hủy, thì bạn có thể bỏ qua lệnh Hủy và hoàn tất thành công. –

Trả lời

9

Cancellation is a cooperative action khi làm việc với Thư viện song song nhiệm vụ và có, việc hủy được khuyến nghị là thao tác nhanh.

Hãy nhớ rằng đây là số hủy, không phải là hủy và xóa. Nếu bạn có các thao tác bổ sung mà bạn cần thực hiện như là kết quả của việc hủy, thì các hoạt động đó sẽ xảy ra bên ngoài tác vụ gốc đã bị hủy.

Lưu ý rằng điều này không ngăn cản bạn gọi ContinueWith và thực hiện một hoạt động trong một mớiTask mà sẽ kiểm tra xem nếu IsCanceled property lợi nhuận true và sau đó thực hiện việc dọn dẹp dựa trên đó.

Điểm mấu chốt ở đây là bạn không muốn chặn bản gốc Task đã bị hủy, nhưng bạn được tự do bắt đầu Task mới để thực hiện bất kỳ việc dọn dẹp nào bạn cần thực hiện do hủy.

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