2012-03-06 34 views
7

Tôi có một phương pháp với cơ cấu như sau:công tác tổng hợp và xử lý lỗi với TPL

public Task InitializeAsync() 
{ 
    var taskCompletionSource = new TaskCompletionSource<bool>(); 

    Task firstTask = ...; 

    // secondTask calls taskCompletionSource.TrySetResult(true) once it considers itself "done" 
    Task secondTask = firstTask.ContinueWith(..., TaskContinuationOptions.OnlyOnRanToCompletion); 

    Action<TasK> errorContinuation = x => 
     { 
      taskCompletionSource.SetException(e.Exception); 
     }; 

    firstTask.ContinueWith(errorContinuation, TaskContinuationOptions.OnlyOnFaulted); 
    secondTask.ContinueWith(errorContinuation, TaskContinuationOptions.OnlyOnFaulted); 

    return taskCompletionSource.Task; 
} 

Quan trọng:

  • nhiệm vụ được trả về bởi InitializeAsync không được xem là hoàn thành cho đến khi secondTask quyết định để
  • secondTask chỉ chạy nếu firstTask thành công
  • lỗi của firstTask hoặc secondTask làm cho tác vụ tổng thể thất bại

Điều tôi đang tự hỏi là liệu có một cách đơn giản, rõ ràng hơn để thể hiện điều này trong khi đạt được cùng một chức năng hay không. Tôi đang sử dụng .NET 4.0 nhưng tôi quan tâm đến việc liệu 4.5 có làm cho việc này dễ dàng hơn không.

+1

in 4.5 bạn có thể thực hiện việc này với các tính năng đang chờ/không đồng bộ và thử/bắt bằng cách chỉ cần cắm các tác vụ vào bên trong hàm async – Carsten

+0

Tôi đã gặp vấn đề tương tự gần đây và đi xuống cùng một tuyến đường cho đến khi tôi tìm thấy bài đăng blog của Stephen Làm phiền câu trả lời của Gideon liên kết đến. Đó là sạch hơn và rõ ràng hơn xử lý tất cả các trường hợp góc hơn nỗ lực ban đầu của tôi tại một giải pháp. – shambulator

Trả lời

5

Đối với .NET 4.0, tôi đã sử dụng một ý tưởng từ this blog article nhiệm vụ chuỗi như bạn mô tả. Cụ thể, hãy xem phần có tiêu đề Sau đó,. Không phải là phiên bản của ông hy vọng bạn vượt qua trong một hàm trả về một nhiệm vụ thay vì chỉ đi qua một phương pháp như bạn sẽ đến ContinueWith

Là một sang một bên, Then giúp bạn khá gần với SelectMany bạn sẽ cần để có thể chuỗi các nhiệm vụ qua LINQ từ các mệnh đề. Tôi đề cập đến điều này chủ yếu là một tùy chọn cú pháp cho đến khi async/await trong .NET 4.5, mặc dù tôi không thực sự sử dụng bản thân mình.

+0

Đây là một giải pháp sạch, chung chung mà tôi ngạc nhiên không có trong BCL, mặc dù 'TaskCompletionSource' chắc chắn làm cho nó đủ đơn giản để thực hiện. Nếu bạn muốn chữ ký giống như 'ContinueWith', bạn phải cung cấp quá tải để chỉ định mã thông báo hủy, trình lên lịch, v.v. – shambulator

+1

Đây là lỗ chính xác trong sự hiểu biết của tôi yêu cầu điền. Cảm ơn rất nhiều. –

0

Một lựa chọn khác là tạo ra hai nhiệm vụ của bạn là nhiệm vụ con đính kèm (lồng vào bên trong một nhiệm vụ cha mẹ mà bạn quay trở lại)

Nhiệm vụ cha mẹ sẽ không hoàn thành cho đến khi nhiệm vụ con kèm theo đầy đủ. Lỗi con được coi là lỗi cha.

http://msdn.microsoft.com/en-us/library/dd997417.aspx

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