ฉันยังใหม่กับการเขียนโปรแกรมแบบอะซิงโครนัสใน C# และฉันยังคงสับสนเกี่ยวกับบางสิ่ง ฉันได้อ่านแล้วว่าหลังจาก .NET 4.5 ไม่แนะนำ APM และ EAP สำหรับการพัฒนาใหม่อีกต่อไป เนื่องจาก TAP ควรจะแทนที่ (แหล่งที่มา)
ฉันคิดว่าฉันเข้าใจวิธีการทำงานของ async/await และสามารถใช้เพื่อดำเนินการ IO ที่มีวิธีการ async ได้ ตัวอย่างเช่น ฉันสามารถเขียนวิธี async ที่รอผลลัพธ์ GetStringAsync ของ HttpWebClient เนื่องจากมีการประกาศเป็นวิธี async นั่นเยี่ยมมาก
คำถามของฉันคือ จะเกิดอะไรขึ้นถ้าเรามีการดำเนินการ IO ที่เกิดขึ้นในวิธีการที่ไม่ได้ประกาศเป็นอะซิงก์ เช่นนี้: สมมติว่าฉันมี API ที่มีวิธีการ
string GetResultFromWeb()
ซึ่งสอบถามบางสิ่งจากเว็บ และฉันมีคำถามมากมายที่ต้องทำ และฉันต้องใช้วิธีนี้เพื่อดำเนินการดังกล่าว จากนั้นฉันจะต้องประมวลผลผลลัพธ์การสืบค้นแต่ละรายการ ฉันเข้าใจว่าฉันจะทำเช่นนี้ถ้านั่นเป็นวิธี async:
Task<string> getResultTask = GetResultFromWeb(myUrl);
// Do whatever I need to do that doesn't need the query result
string result = await getResultTask;
Process(result);
แต่เนื่องจากไม่ใช่ ฉันจึงไม่สามารถรอได้ -- มันบอกฉันว่า string is not awaitable ดังนั้นคำถามของฉันคือ: มีวิธีใดในการดำเนินการ IO เหล่านี้แบบอะซิงโครนัสโดยไม่ต้องสร้างหนึ่งเธรดสำหรับแต่ละแบบสอบถามหรือไม่ หากทำได้ ฉันอยากจะสร้างเธรดให้น้อยที่สุดเท่าที่จะเป็นไปได้ โดยไม่ต้องบล็อกเธรดใดๆ
วิธีหนึ่งที่ฉันพบว่าทำได้คือการใช้ APM โดยทำตามบทความนี้ จาก Jeffrey Richter จากนั้นในวิธี Begin ของฉัน ฉันเรียก ThreadPool.QueueWorkItem(GetResultFromWeb, asyncResult) แบบนี้:
public class A {
private void DoQuery(Object ar){
AsyncResult<string> asyncResult = (AsyncResult<string>) ar;
string result = GetResultFromWeb();
asyncResult.SetAsCompleted(result, false);
}
public IAsyncResult BeginQuery(AsyncCallback){
AsyncResult<string> asyncResult = new AsyncResult<string>(callback, this);
ThreadPool.QueueUserWorkItem(DoQuery, asyncResult);
return asyncResult;
}
public string EndQuery(IAsyncResult ar){
AsyncResult<string> asyncResult = (AsyncResult<string>)ar;
return asyncResult.EndInvoke();
}
}
จากนั้นฉันใช้ AsyncEnumerator และเริ่มต้น (BeginQuery) หลาย ๆ แบบสอบถามและประมวลผลผลลัพธ์เมื่อแต่ละรายการเสร็จสิ้น (โดยใช้ผลตอบแทนผลตอบแทน / EndQuery) ดูเหมือนว่าจะทำงานได้ดี แต่หลังจากอ่านมามากจน APM ล้าสมัย ฉันสงสัยว่าฉันจะทำอย่างไรโดยใช้ TAP นอกจากนี้ มีปัญหาใดๆ กับแนวทาง APM นี้หรือไม่
ขอบคุณ!