2012-08-23 10 views
37

Tôi đang cố gắng quấn quanh đầu TPL, các tính năng async/await mới trong C# 5 và những bí ẩn của TaskCompletionSource.TaskCompletionSource: Khi nào sử dụng SetResult() so với TrySetResult(), v.v.

Một điều mà không phải là rõ ràng với tôi là khi nào sử dụng SetResult, SetException, và SetCancel so TrySetResult, TrySetExceptionTrySetCancel.

Đây là những gì MSDN đã nói:

Thao tác này sẽ trả về false nếu Task là đã có trong một trong ba trạng thái cuối: RanToCompletion, đứt gãy, hoặc bị hủy.

Phương pháp này cũng trả về false nếu Tác vụ cơ bản có đã được xử lý.

Ok, tôi hiểu điều đó, nhưng nó thực sự không đưa ra bất kỳ hướng dẫn nào về thời điểm hoặc lý do sử dụng cái kia.

Vì vậy, thỏa thuận là gì?

Trả lời

46

I nghi ngờ vấn đề là nếu chỉ có một thứ sẽ được thiết lập kết quả, chỉ cần gọi SetResult vv. Nếu bạn kết thúc cuộc gọi SetResult hai lần, điều đó cho biết lỗi. (Tương tự như vậy nếu TaskCompletionSource đã được xử lý.)

Nếu bạn có một số chủ đề mà tất cả đều có thể cố gắng đặt kết quả cùng một lúc (ví dụ như ở đó để cho biết kết quả đầu tiên của một số cuộc gọi dịch vụ web song song)) sau đó sử dụng TrySetResult, vì nó hoàn toàn hợp lý cho nhiều chủ đề để "thử" để đặt kết quả, không biết liệu một chủ đề khác đã được đặt chưa.

Tôi chưa thấy bất kỳ hướng dẫn chính thức nào về điều đó, nhưng điều đó có ý nghĩa.

+8

tức là, lý do duy nhất bạn cần gọi là 'TrySetResult' là nếu bạn đặt kết quả nhiều lần. 'SetResult'" hoàn thành "liên kết' Task' để gọi 'SetResult' một lần nữa sẽ cố gắng thiết lập kết quả' Task 'sau khi tác vụ đã hoàn thành. ('SetResult' khối cho đến khi' Task' hoàn thành - cũng như 'TrySetResult') Nếu bạn chỉ bao giờ gọi' SetResult' một lần, sau đó bạn sẽ không bao giờ cần 'TrySetResult'. FWIW. Chuỗi 'SetResult' thành' TrySetResult' ... –

+0

Xin cảm ơn các bạn, các bạn đang tạo ra rất nhiều ý nghĩa! – HolySamosa

+0

Cũng lưu ý rằng SetResult trả về 'void' trong khi TrySetResult trả về' bool' vì vậy nếu bạn muốn làm điều gì đó tùy thuộc vào trạng thái nhiệm vụ, thì 'TrySetResult' vừa được kiểm tra vừa thiết lập cùng lúc (nguyên tử?). – chakrit