คำนำ : ฉันกำลังมองหาคำอธิบายไม่ใช่แค่ทางออก ฉันรู้วิธีแก้ปัญหาแล้ว
แม้ว่าจะใช้เวลาหลายวันในการศึกษาบทความ MSDN เกี่ยวกับ Asynchronous Pattern (TAP) แบบใช้งาน, async และรอฉันยังคงสับสนเล็กน้อยเกี่ยวกับรายละเอียดปลีกย่อยบางส่วน
ฉันกำลังเขียนตัวบันทึกสำหรับแอพ Windows Store และฉันต้องการสนับสนุนทั้งการบันทึกแบบอะซิงโครนัสและการซิงโครนัส วิธีการแบบอะซิงโครนัสตาม TAP วิธีการแบบอะซิงโครนัสควรซ่อนทั้งหมดนี้และดูและทำงานเหมือนกับวิธีการทั่วไป
นี่คือวิธีการหลักของการบันทึกแบบอะซิงโครนัส:
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);
}
ตอนนี้วิธีการซิงโครนัสที่สอดคล้องกัน ...
รุ่น 1 :
private void WriteToLog(string text)
{
Task task = WriteToLogAsync(text);
task.Wait();
}
สิ่งนี้ดูถูกต้อง แต่ใช้งานไม่ได้ โปรแกรมทั้งหมดค้างตลอดไป
รุ่น 2 :
อืม .. บางทีงานอาจไม่ได้เริ่มเลยเหรอ?
private void WriteToLog(string text)
{
Task task = WriteToLogAsync(text);
task.Start();
task.Wait();
}
สิ่งนี้จะพ่น InvalidOperationException: Start may not be called on a promise-style task.
รุ่น 3:
อืม .. Task.RunSynchronously
ดูเหมือนว่าจะมีแนวโน้ม
private void WriteToLog(string text)
{
Task task = WriteToLogAsync(text);
task.RunSynchronously();
}
สิ่งนี้จะพ่น InvalidOperationException: RunSynchronously may not be called on a task not bound to a delegate, such as the task returned from an asynchronous method.
เวอร์ชัน 4 (โซลูชัน):
private void WriteToLog(string text)
{
var task = Task.Run(async () => { await WriteToLogAsync(text); });
task.Wait();
}
วิธีนี้ใช้ได้ผล ดังนั้น 2 และ 3 จึงเป็นเครื่องมือที่ผิด แต่ 1 มีอะไรผิดปกติกับ 1 และอะไรคือความแตกต่างของ 4? สิ่งที่ทำให้ 1 ทำให้เกิดการแช่แข็ง? มีปัญหากับวัตถุภารกิจหรือไม่? มีการหยุดชะงักที่ไม่ชัดเจนหรือไม่?