สิ่งนี้อ้างถึงhttp://blogs.msdn.com/b/pfxteam/archive/2012/02/12/10266988.aspx , http://winrtstoragehelper.codeplex.com/ , ที่เก็บแอพ Windows 8 และ. net 4.5
นี่คือมุมของฉันในเรื่องนี้:
คุณลักษณะภาษา async / await ทำให้หลายสิ่งค่อนข้างง่าย แต่ก็ยังแนะนำสถานการณ์ที่ไม่ค่อยพบก่อนที่จะใช้การโทรแบบ async: reentrance
นี่เป็นเรื่องจริงโดยเฉพาะอย่างยิ่งสำหรับตัวจัดการเหตุการณ์เพราะสำหรับหลาย ๆ เหตุการณ์คุณไม่มีเงื่อนงำเกี่ยวกับสิ่งที่เกิดขึ้นหลังจากที่คุณกลับมาจากตัวจัดการเหตุการณ์ สิ่งหนึ่งที่อาจเกิดขึ้นจริงคือวิธีการ async ที่คุณรออยู่ในตัวจัดการเหตุการณ์แรกถูกเรียกจากตัวจัดการเหตุการณ์อื่นที่ยังคงอยู่ในเธรดเดียวกัน
นี่เป็นสถานการณ์จริงที่ฉันเจอในแอพ windows 8 App store: แอพของฉันมีสองเฟรม: การเข้าและออกจากเฟรมฉันต้องการโหลด / เซฟข้อมูลบางอย่างไปยังไฟล์ / ที่เก็บข้อมูล เหตุการณ์ OnNavigatedTo / From ถูกใช้สำหรับการบันทึกและการโหลด การบันทึกและการโหลดทำได้โดยฟังก์ชั่นยูทิลิตี้ async (เช่นhttp://winrtstoragehelper.codeplex.com/ ) เมื่อนำทางจากเฟรม 1 ถึงเฟรม 2 หรือในทิศทางอื่นโหลด async และการทำงานที่ปลอดภัยจะถูกเรียกและรอ ตัวจัดการเหตุการณ์กลายเป็น async ที่คืนค่าเป็นโมฆะ => ไม่สามารถรอได้
อย่างไรก็ตามการดำเนินการเปิดไฟล์ครั้งแรก (ให้บอกว่า: ภายในฟังก์ชั่นการบันทึก) ของยูทิลิตี้ก็เป็น async เช่นกันดังนั้นการรอคอยครั้งแรกก็กลับมาควบคุมเฟรมเวิร์กซึ่งบางครั้งเรียกยูทิลิตี้อื่น ๆ ขณะนี้การโหลดพยายามเปิดไฟล์เดียวกันและหากไฟล์นั้นเปิดอยู่ในตอนนี้สำหรับการดำเนินการบันทึกล้มเหลวด้วยข้อยกเว้น ACCESSDENIED
วิธีแก้ปัญหาขั้นต่ำสำหรับฉันคือรักษาความปลอดภัยการเข้าถึงไฟล์ผ่านการใช้และ AsyncLock
private static readonly AsyncLock m_lock = new AsyncLock();
...
using (await m_lock.LockAsync())
{
file = await folder.GetFileAsync(fileName);
IRandomAccessStream readStream = await file.OpenAsync(FileAccessMode.Read);
using (Stream inStream = Task.Run(() => readStream.AsStreamForRead()).Result)
{
return (T)serializer.Deserialize(inStream);
}
}
โปรดทราบว่าโดยทั่วไปแล้วการล็อคของเขาจะล็อคการทำงานของไฟล์ทั้งหมดสำหรับยูทิลิตี้ด้วยการล็อคเพียงครั้งเดียวซึ่งมีความแข็งแรงเกินความจำเป็น แต่ก็ใช้ได้ดีสำหรับสถานการณ์ของฉัน
ที่นี่ คือโครงการทดสอบของฉัน: แอพ windows 8 app store ที่มีการทดสอบการโทรสำหรับรุ่นดั้งเดิมจากhttp://winrtstoragehelper.codeplex.com/และเวอร์ชันที่แก้ไขของฉันที่ใช้ AsyncLock จาก Stephen Toub http: //blogs.msdn co.th / b / pfxteam / เก็บ / 2012 / 12/02 / 10266988.aspxco.th
ฉันขอแนะนำลิงก์นี้ได้ไหม:
http://www.hanselman.com/blog/ComparingTwoTechniquesInNETAsynchronousCoordinationPrimitives.aspx