2015-07-08 18 views
7

Tôi muốn làm điều gì đó như thế này:async đang chờ bắt ngoại lệ - tôi đang ở chủ đề nào?

public async Task<int> DoWork(int parameter) { 
    try { 
     await OperationThatMayCompleteSynchronously(parameter); 
    } catch(Exception) e { 
     if(completedSynchronously) 
      doSyncThing(); 
     else 
      doAsyncThing(); 
    } 
} 

Lưu ý: Tôi đang chạy nhiệm vụ trên hồ bơi thread, vì vậy không có bối cảnh async.

Tôi muốn có thể biết sự khác biệt giữa ngoại lệ được ném ngay lập tức và tôi vẫn đang ở trên chuỗi gọi (ví dụ: parameter không hợp lệ khiến chức năng hủy bỏ) và ngoại lệ được ném khi tác vụ không đồng bộ hoàn thành và tôi đang sử dụng một số chuỗi gọi lại ngẫu nhiên khác (ví dụ: lỗi mạng)

Tôi có thể làm cách nào để đạt được điều này nếu tôi không sử dụng await và chỉ sử dụng ContinueWith trên hoạt động không đồng bộ. có thể sử dụng await?

+1

Hãy nhớ rằng nếu 'OperationThatMayCompleteSynchronously' là một phương thức không đồng bộ, tất cả ngoại lệ sẽ được lưu trữ trong tác vụ và sẽ không có ngoại lệ nào được ném đồng bộ – i3arnon

Trả lời

10

Store nhiệm vụ trong một biến:

var task = OperationThatMayCompleteSynchronously(parameter); //may throw 

Sau đó đợi nó:

await task; //may throw 

Bằng cách đó bạn có thể phân biệt giữa hai nguồn gốc cho một ngoại lệ tiềm năng.

Lưu ý rằng các phương pháp async không bao giờ ném trực tiếp. Họ vượt qua ngoại lệ thông qua nhiệm vụ họ quay trở lại. Điều này đúng ngay cả khi "xác nhận" ném mà thực hiện trước khi chờ đợi đầu tiên.

+2

ohhhh ... đơn giản như vậy khi bạn chỉ ra như vậy –

+1

@OrionEdwards, nhận được 100% hành vi mà bạn muốn, bạn cần phải sửa đổi phần trên để thêm một cái gì đó như thế này: 'var task = OperationThatMayCompleteSynchronously (tham số); if (task.IsFaulted) task.GetAwaiter(). GetResult(); ... '. Kiểm tra [this] (http://stackoverflow.com/a/21082631/1768303). – Noseratio

+1

@Noseratio bạn có thể giải thích điều gì sẽ thực hiện được không? Có vẻ như chờ đợi làm điều đó. – usr

1

Thay vì chờ, bạn có thể gọi Wait() hoặc Result, vì bạn tuyên bố rằng không có bối cảnh đồng bộ hóa và nếu ngoại lệ bị bắt là AggregateException, nó không được đưa vào chuỗi cuộc gọi.

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