Ý tôi là đây:
public Task<SomeObject> GetSomeObjectByTokenAsync(int id)
{
string token = repository.GetTokenById(id);
if (string.IsNullOrEmpty(token))
{
return Task.FromResult(new SomeObject()
{
IsAuthorized = false
});
}
else
{
return repository.GetSomeObjectByTokenAsync(token).ContinueWith(t =>
{
t.Result.IsAuthorized = true;
return t.Result;
});
}
}
Phương pháp nêu trên có thể được chờ đợi và tôi nghĩ rằng nó rất giống với những gì T hỏi dựa trên Một đồng bộ P attern đề nghị làm gì? (Các mẫu khác mà tôi biết là các mẫu APM và EAP .)
Bây giờ, những gì về mã sau đây:
public async Task<SomeObject> GetSomeObjectByToken(int id)
{
string token = repository.GetTokenById(id);
if (string.IsNullOrEmpty(token))
{
return new SomeObject()
{
IsAuthorized = false
};
}
else
{
SomeObject result = await repository.GetSomeObjectByTokenAsync(token);
result.IsAuthorized = true;
return result;
}
}
Sự khác biệt chính ở đây là phương thức này async
và nó sử dụng các await
từ khóa - vậy điều này có gì thay đổi so với phương pháp được viết trước đó? Tôi biết nó cũng có thể - được chờ đợi. Bất kỳ phương thức nào trả về Nhiệm vụ đều có thể cho vấn đề đó, trừ khi tôi nhầm.
Tôi biết về máy trạng thái được tạo bằng các câu lệnh chuyển đổi đó bất cứ khi nào một phương thức được gắn nhãn là async
và tôi biết rằng await
chính nó không sử dụng luồng nào - nó hoàn toàn không chặn, luồng chỉ đơn giản là thực hiện các thao tác khác, cho đến khi nó được gọi lại để tiếp tục thực thi đoạn mã trên.
Nhưng sự khác biệt cơ bản giữa hai phương pháp là gì, khi chúng ta gọi chúng bằng await
từ khóa? Có sự khác biệt nào không, và nếu có - cái nào được ưa thích?
EDIT: Tôi cảm thấy như đoạn mã đầu tiên được ưa thích, bởi vì chúng có hiệu quả bõ mẫu âm chót các async / chờ đợi từ khóa, mà không cần bất kỳ hậu quả - chúng tôi trả lại một nhiệm vụ mà sẽ tiếp tục thực hiện của nó đồng bộ, hoặc một nhiệm vụ đã hoàn thành trên con đường nóng (có thể lưu trữ).
result.IsAuthorized = true
sẽ được chạy trên nhóm luồng, trong khi trong ví dụ thứ hai, nó có thể được chạy trên cùng một luồng đã gọiGetSomeObjectByToken
(nếu nó đã đượcSynchronizationContext
cài đặt trên nó, ví dụ như đó là luồng UI). Hành vi nếuGetSomeObjectByTokenAsync
ném một ngoại lệ cũng sẽ hơi khác nhau. Nói chungawait
được ưa thích hơnContinueWith
, vì nó hầu như luôn luôn dễ đọc hơn.