Lời nói đầu : Tôi đang tìm kiếm một lời giải thích, không chỉ là một giải pháp. Tôi đã biết giải pháp.
Mặc dù đã dành nhiều ngày để nghiên cứu các bài viết MSDN về Mẫu không đồng bộ dựa trên tác vụ (TAP), không đồng bộ và chờ đợi, tôi vẫn hơi bối rối về một số chi tiết tốt hơn.
Tôi đang viết một trình ghi nhật ký cho Ứng dụng Windows Store và tôi muốn hỗ trợ cả ghi nhật ký không đồng bộ và đồng bộ. Các phương thức không đồng bộ tuân theo TAP, các phương thức đồng bộ sẽ ẩn tất cả điều này, và trông và hoạt động như các phương thức thông thường.
Đây là phương pháp cốt lõi của ghi nhật ký không đồng bộ:
private async Task WriteToLogAsync(string text)
{
StorageFolder folder = ApplicationData.Current.LocalFolder;
StorageFile file = await folder.CreateFileAsync("log.log",
CreationCollisionOption.OpenIfExists);
await FileIO.AppendTextAsync(file, text,
Windows.Storage.Streams.UnicodeEncoding.Utf8);
}
Bây giờ phương thức đồng bộ tương ứng ...
Phiên bản 1 :
private void WriteToLog(string text)
{
Task task = WriteToLogAsync(text);
task.Wait();
}
Điều này có vẻ đúng, nhưng nó không hoạt động. Toàn bộ chương trình đóng băng mãi mãi.
Phiên bản 2 :
Hmm .. Có lẽ nhiệm vụ chưa được bắt đầu?
private void WriteToLog(string text)
{
Task task = WriteToLogAsync(text);
task.Start();
task.Wait();
}
Cái này ném InvalidOperationException: Start may not be called on a promise-style task.
Phiên bản 3:
Hmm .. Task.RunSynchronously
âm thanh đầy hứa hẹn.
private void WriteToLog(string text)
{
Task task = WriteToLogAsync(text);
task.RunSynchronously();
}
Cái này ném InvalidOperationException: RunSynchronously may not be called on a task not bound to a delegate, such as the task returned from an asynchronous method.
Phiên bản 4 (giải pháp):
private void WriteToLog(string text)
{
var task = Task.Run(async () => { await WriteToLogAsync(text); });
task.Wait();
}
Những công việc này. Vì vậy, 2 và 3 là các công cụ sai. Nhưng 1? Có gì sai với 1 và sự khác biệt của 4 là gì? Điều gì làm cho 1 gây ra đóng băng? Có một số vấn đề với các đối tượng nhiệm vụ? Có một bế tắc không rõ ràng?