2014-05-08 15 views
10

Giả sử có một thư viện phục vụ với một phương pháp như thế nàyReturn Task hoặc chờ đợi và ConfigureAwait (false)

public async Task<Person> GetPersonAsync(Guid id) { 
    return await GetFromDbAsync<Person>(id); 
} 

Sau khi thực hành tốt nhất cho SynchronizationContext là tốt hơn để sử dụng

public async Task<Person> GetPersonAsync(Guid id) { 
    return await GetFromDbAsync<Person>(id).ConfigureAwait(false); 
} 

Nhưng khi bạn chỉ có một hoạt động (tôi nghĩ) là tốt hơn để trả lại tác vụ trực tiếp. Xem At the end of an async method, should I return or await?

public Task<Person> GetPersonAsync(Guid id) { 
    return GetFromDbAsync<Person>(id); 
} 

Trong trường hợp cuối cùng này, bạn không thể sử dụng ConfigureAwait (false) vì phương pháp này là không chờ đợi.

Giải pháp tốt nhất (và lý do) là gì?

+1

Tôi nghĩ người cuối cùng (phái đoàn) là rõ ràng nhất và không liên quan đến việc tạo ra máy nhà nước bổ sung. Trừ khi bạn đang làm * cái gì khác * bên trong phương thức phụ thuộc vào kết quả cuộc gọi không đồng bộ, tôi không thấy điểm nào trong việc sử dụng 'await'. –

+0

Điều cuối cùng có ý nghĩa nhất đối với tôi. Nó trả về một nhiệm vụ mà bạn có thể chờ đợi từ bất cứ nơi nào bạn đang gọi GetPersonAsync –

+0

Vì vậy, giải pháp trả lại tác vụ trực tiếp không nắm bắt được SynchronizationContext? – sevenmy

Trả lời

10

Mỗi tùy chọn có thông tin cụ thể của riêng mình, hãy kiểm tra thisthis. Nếu bạn hiểu chúng, bạn có thể quyết định cái nào là tốt nhất cho bạn.

Vì vậy, giải pháp trả lại tác vụ trực tiếp không nắm bắt được SynchronizationContext?

Đây không phải là nhiệm vụ nắm bắt ngữ cảnh đồng bộ hóa hiện tại. Đó là TaskAwaiter.OnCompleted (hoặc ConfiguredTaskAwaitable.OnCompleted, trong trường hợp ConfigureAwait), được gián tiếp gọi bởi mã được tạo bởi trình biên dịch C# như là một phần của câu lệnh await cho tác vụ.

Vì vậy, nếu bạn không sử dụng await, bạn không nên lo lắng về việc chụp SynchronizationContext, điều đó không xảy ra một cách kỳ diệu. Điều này có thể làm cho tùy chọn thứ 3 là thuận lợi nhất, nhưng hãy ghi nhớ exception propagation behavior của nó.

+0

cảm ơn. Tôi nghĩ đây là một lựa chọn rất cụ thể về miền. Có bất kỳ sự khác biệt nào nếu phương pháp được gọi là thực sự không đồng bộ? Ví dụ một truy vấn không đồng bộ với EF (xử lý lỗi là quan trọng). – sevenmy

+1

Một đọc tốt khác là: [Hiệu suất không đồng bộ: Hiểu chi phí của Async và Await] (http://msdn.microsoft.com/en-us/magazine/hh456402.aspx) – sevenmy

+0

@sevenmy, Phương thức 'async Task' sẽ không bao giờ ném cho đến khi bạn quan sát nhiệm vụ bằng 'nhiệm vụ chờ đợi',' task.Wait() ', hoặc' task.Result'. OTOH, phương thức 'Task' không đồng bộ có thể ném ngay lập tức. ** Tuy nhiên **, trong mã khách hàng của bạn, bạn không nên đưa ra giả định. Luôn luôn mã như nó có thể ném một trong hai đồng bộ (trên cùng một khung stack) hoặc không đồng bộ. – Noseratio

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