เพื่อการเรียนรู้ที่เร็วที่สุด ..
ทำความเข้าใจกับโฟลว์การประมวลผลเมธอด (พร้อมไดอะแกรม): 3 นาที
วิปัสสนาคำถาม (สาเกการเรียนรู้): 1 นาที
ได้อย่างรวดเร็วผ่านไวยากรณ์น้ำตาล: 5 นาที
แบ่งปันความสับสนของผู้พัฒนา: 5 นาที
ปัญหา: เปลี่ยนการใช้งานรหัสโลกปกติเป็นรหัส Async ได้อย่างรวดเร็ว: 2 นาที
ไปที่ไหนต่อไป?
ทำความเข้าใจกับโฟลว์การประมวลผลเมธอด (พร้อมไดอะแกรม): 3 นาที
ในภาพนี้เพียงแค่มุ่งเน้นที่ # 6 (ไม่มีอะไรเพิ่มเติม)
ที่ # 6 ขั้นตอน: การดำเนินการหยุดลงที่นี่เนื่องจากการทำงานไม่เพียงพอ ในการดำเนินการต่อต้องได้รับผลลัพธ์จาก getStringTask (ชนิดของฟังก์ชัน) ดังนั้นจึงใช้await
โอเปอเรเตอร์เพื่อระงับความคืบหน้าและให้การควบคุม (ผลตอบแทน) แก่ผู้โทร (ของวิธีการที่เราอยู่) การเรียก getStringTask ที่แท้จริงเกิดขึ้นก่อนหน้านี้ใน # 2 ที่ # 2 สัญญาถูกสร้างขึ้นเพื่อส่งคืนผลลัพธ์สตริง แต่มันจะส่งคืนผลลัพธ์เมื่อใด เราควร (# 1: AccessTheWebAsync) โทรครั้งที่ 2 อีกครั้งหรือไม่ ใครได้รับผลลัพธ์ # 2 (คำสั่งการเรียก) หรือ # 6 (กำลังรอคำสั่ง)
ผู้เรียกภายนอกของ AccessTheWebAsync () ก็กำลังรออยู่เช่นกัน ดังนั้นผู้โทรกำลังรอ AccessTheWebAsync และ AccessTheWebAsync กำลังรอให้ GetStringAsync อยู่ในขณะนี้ สิ่งที่น่าสนใจคือ AccessTheWebAsync ทำงานบางอย่างก่อนรอ (# 4) บางทีเพื่อประหยัดเวลาจากการรอ อิสระในการใช้มัลติทาสก์เดียวกันนี้ยังมีให้สำหรับผู้โทรภายนอก (และผู้โทรทุกคนในเครือข่าย) และนี่เป็นข้อดีที่สุดของ 'async' thingy! คุณรู้สึกเหมือนซิงโครนัส .. หรือปกติ แต่ไม่ใช่
โปรดจำไว้ว่าวิธีการส่งคืนแล้ว (# 2) ไม่สามารถส่งคืนได้อีก (ไม่มีครั้งที่สอง) แล้วผู้โทรจะรู้ได้อย่างไร มันเป็นเรื่องของTasks! ภารกิจผ่านไปแล้ว งานกำลังรอ (ไม่ใช่วิธีไม่ใช่ค่า) ค่าจะถูกตั้งค่าในงาน สถานะงานจะถูกตั้งค่าให้เสร็จสมบูรณ์ ผู้โทรเพียงแค่ตรวจสอบงาน (# 6) ดังนั้น 6 # คือคำตอบของผู้ที่ได้ผลลัพธ์ เพิ่มเติมอ่านในภายหลังที่นี่
คำถามวิปัสสนาเพื่อประโยชน์ในการเรียนรู้: 1 นาที
ให้เราปรับคำถามเล็กน้อย:
อย่างไรและเมื่อไหร่ที่จะใช้และ ? async
await
Tasks
เพราะการเรียนรู้Task
จะครอบคลุมอีกสองส่วนโดยอัตโนมัติ (และตอบคำถามของคุณ)
ได้อย่างรวดเร็วผ่านไวยากรณ์น้ำตาล: 5 นาที
ก่อนการแปลง (วิธีดั้งเดิม)
internal static int Method(int arg0, int arg1)
{
int result = arg0 + arg1;
IO(); // Do some long running IO.
return result;
}
วิธีการ Task-ified เพื่อเรียกวิธีการดังกล่าว
internal static Task<int> MethodTask(int arg0, int arg1)
{
Task<int> task = new Task<int>(() => Method(arg0, arg1));
task.Start(); // Hot task (started task) should always be returned.
return task;
}
พวกเราพูดถึงการรอคอยหรือ async? ไม่โทรตามวิธีข้างต้นแล้วคุณจะได้งานที่สามารถตรวจสอบได้ คุณรู้อยู่แล้วว่างานที่ส่งกลับ .. จำนวนเต็ม
การเรียกใช้งานนั้นยุ่งยากเล็กน้อยและนั่นคือเมื่อคำหลักเริ่มปรากฏขึ้น ให้เราเรียก MethodTask ()
internal static async Task<int> MethodAsync(int arg0, int arg1)
{
int result = await HelperMethods.MethodTask(arg0, arg1);
return result;
}
รหัสเดียวกันข้างต้นเพิ่มเป็นภาพด้านล่าง:
- เรากำลังรอให้งานเสร็จ ดังนั้น
await
- เนื่องจากเราใช้คอยเราต้องใช้
async
(ไวยากรณ์บังคับ)
- MethodAsync พร้อมด้วย
Async
คำนำหน้า (มาตรฐานการเข้ารหัส)
await
เข้าใจง่าย แต่ส่วนที่เหลืออีกสอง ( async
, Async
) อาจไม่ใช่ :) ก็ควรทำให้คอมไพเลอร์เข้าใจได้มากกว่านี้อีกอ่านต่อที่นี่
มี 2 ส่วน
- สร้าง 'งาน'
- สร้างน้ำตาลประโยคเพื่อเรียกใช้งาน (
await+async
)
โปรดจำไว้ว่าเรามีโทรภายนอกเพื่อ AccessTheWebAsync () และโทรที่ไม่ได้หวงทั้ง ... คือมันต้องการที่เหมือนกันawait+async
มากเกินไป และห่วงโซ่ยังคง แต่จะมีเสมอTask
ที่ปลายด้านหนึ่ง
ไม่เป็นไร แต่ผู้พัฒนารายหนึ่งรู้สึกประหลาดใจที่พบ # 1 (งาน) หายไป ...
แบ่งปันความสับสนของผู้พัฒนา: 5 นาที
นักพัฒนาซอฟต์แวร์ทำผิดพลาดที่ไม่ใช้งานTask
แต่ก็ยังใช้งานได้! พยายามที่จะเข้าใจคำถามและเพียงแค่คำตอบที่ได้รับการยอมรับให้ที่นี่ หวังว่าคุณจะได้อ่านและเข้าใจอย่างเต็มที่ บทสรุปคือเราอาจไม่เห็น / ใช้งาน 'งาน' แต่นำไปใช้ที่ไหนสักแห่งในระดับผู้ปกครอง ในตัวอย่างของเราที่เรียกว่าบิวด์ที่สร้างไว้แล้วMethodAsync()
นั้นเป็นวิธีที่ง่ายกว่าการใช้เมธอดนั้นด้วยTask
( MethodTask()
) ตัวเราเอง นักพัฒนาส่วนใหญ่พบว่าเป็นการยากที่จะนำหน้าTasks
ในขณะที่แปลงรหัสเป็นแบบอะซิงโครนัส
เคล็ดลับ: ลองค้นหาการใช้ Async ที่มีอยู่ (เช่นMethodAsync
หรือToListAsync
) เพื่อเอาท์ซอร์สความยากลำบาก ดังนั้นเราจะต้องจัดการกับ Async และรอ (ซึ่งเป็นเรื่องง่ายและค่อนข้างคล้ายกับรหัสปกติ)
ปัญหา: เปลี่ยนการใช้งานรหัสโลกปกติเป็นการดำเนินการ Async อย่างรวดเร็ว: 2 นาที
บรรทัดรหัสที่แสดงด้านล่างในชั้นข้อมูลเริ่มแตก (หลายแห่ง) เพราะเราอัปเดตโค้ดบางส่วนของเราจาก. Net framework 4.2. * เป็น. Net core เราต้องแก้ไขสิ่งนี้ใน 1 ชั่วโมงทั่วแอปพลิเคชัน!
var myContract = query.Where(c => c.ContractID == _contractID).First();
easypeasy!
- เราติดตั้งแพคเกจ nuget EntityFramework เพราะมันมี QueryableExtensions หรืออีกนัยหนึ่งก็ไม่ดำเนินการ Async (งาน) เพื่อให้เราสามารถอยู่รอดได้ด้วยง่าย
Async
และawait
ในรหัส
- namespace = Microsoft.EntityFrameworkCore
สายรหัสโทรศัพท์เปลี่ยนไปเช่นนี้
var myContract = await query.Where(c => c.ContractID == _contractID).FirstAsync();
ลายเซ็นวิธีเปลี่ยนจาก
Contract GetContract(int contractnumber)
ถึง
async Task<Contract> GetContractAsync(int contractnumber)
วิธีการโทรก็ได้รับผลกระทบด้วย: GetContractAsync(123456);
ถูกเรียกว่าGetContractAsync(123456).Result;
เราเปลี่ยนทุกที่ใน 30 นาที!
แต่สถาปนิกบอกเราว่าอย่าใช้ห้องสมุด EntityFramework เพียงแค่นี้! โอ๊ะ! ละคร! จากนั้นเราทำการปรับใช้งานแบบกำหนดเอง (yuk) ซึ่งคุณจะรู้ได้อย่างไร ยังง่าย! .. ยังคง yuk ..
ไปที่ไหนต่อไป?
มีวิดีโอด่วนที่ยอดเยี่ยมที่เราสามารถรับชมเกี่ยวกับการแปลงการโทรแบบซิงโครนัสเป็นอะซิงโครนัสใน ASP.Net Coreซึ่งอาจเป็นไปได้ที่ทิศทางที่เราจะอ่านหลังจากนี้