อันดับแรกเรามาทำความเข้าใจกับคำศัพท์บางคำ: "asynchronous" ( async) หมายความว่ามันอาจให้การควบคุมกลับไปที่เธรดการโทรก่อนที่จะเริ่ม ในasyncวิธีการเหล่านั้นคะแนน "ผลผลิต" เป็นawaitนิพจน์
สิ่งนี้แตกต่างอย่างมากจากคำว่า "asynchronous" ซึ่งเป็น (mis) ที่ใช้โดยเอกสารคู่มือ MSDN เป็นเวลาหลายปีเพื่อหมายถึง "ดำเนินการบนเธรดพื้นหลัง"
เพื่อทำให้สับสนมากขึ้นปัญหาasyncแตกต่างจาก "รอ" มีบางasyncวิธีการที่มีผลตอบแทนประเภทไม่ได้ awaitable และวิธีการมากมายที่จะกลับประเภท awaitable asyncที่ไม่ได้
พอเกี่ยวกับสิ่งที่พวกเขาไม่ ; นี่คือสิ่งที่พวกเขาเป็น :
asyncคำหลักที่ช่วยให้วิธีการที่ไม่ตรงกัน (นั่นคือมันจะช่วยให้awaitการแสดงออก) asyncวิธีการอาจจะกลับมาTask, Task<T>หรือ void(ถ้าคุณต้อง)
- รูปแบบใดก็ตามที่เป็นไปตามรูปแบบที่แน่นอนสามารถรอได้ ที่พบมากที่สุดประเภท awaitable มีและ
TaskTask<T>
ดังนั้นหากเราเปลี่ยนรูปแบบคำถามของคุณเป็น "ฉันจะเรียกใช้การดำเนินการบนเธรดพื้นหลังในลักษณะที่เป็นไปไม่ได้" คำตอบคือใช้Task.Run:
private Task<int> DoWorkAsync() // No async because the method does not need await
{
return Task.Run(() =>
{
return 1 + 2;
});
}
(แต่รูปแบบนี้เป็นวิธีที่ไม่ดีดูด้านล่าง)
แต่หากคำถามของคุณคือ "ฉันจะสร้างasyncวิธีการที่สามารถให้ผลตอบแทนกลับไปที่ผู้โทรแทนที่จะบล็อก" คำตอบคือประกาศวิธีการasyncและใช้awaitสำหรับคะแนน "ยอม" ของมัน:
private async Task<int> GetWebPageHtmlSizeAsync()
{
var client = new HttpClient();
var html = await client.GetAsync("http://www.example.com/");
return html.Length;
}
ดังนั้นรูปแบบพื้นฐานของสิ่งต่าง ๆ คือการมีasyncโค้ดขึ้นอยู่กับ "awaitables" ในการawaitแสดงออก "awaitables" เหล่านี้อาจเป็นasyncวิธีการอื่นหรือเพียงแค่วิธีปกติที่กลับมารอ วิธีการปกติกลับมาTask/ Task<T> สามารถใช้Task.Runในการดำเนินการโค้ดบนด้ายพื้นหลังหรือ (มากกว่าปกติ) พวกเขาสามารถใช้TaskCompletionSource<T>หรือหนึ่งในทางลัดมัน ( TaskFactory.FromAsync, Task.FromResultฯลฯ ) ฉันไม่แนะนำให้ห่อทั้งวิธีในTask.Run; วิธีการแบบซิงโครนัสควรมีลายเซ็นแบบซิงโครนัสและควรถูกทิ้งไว้กับผู้บริโภคว่าควรห่อในTask.Run:
private int DoWork()
{
return 1 + 2;
}
private void MoreSynchronousProcessing()
{
// Execute it directly (synchronously), since we are also a synchronous method.
var result = DoWork();
...
}
private async Task DoVariousThingsFromTheUIThreadAsync()
{
// I have a bunch of async work to do, and I am executed on the UI thread.
var result = await Task.Run(() => DoWork());
...
}
ฉันมีasync/ awaitแนะนำในบล็อกของฉัน; ในตอนท้ายเป็นแหล่งข้อมูลการติดตามที่ดี เอกสาร MSDN สำหรับasyncนั้นก็ดีเหมือนกัน