Saya baru mengenal pemrograman asinkron di C# dan saya masih bingung tentang beberapa hal. Saya telah membaca bahwa setelah .NET 4.5, APM dan EAP tidak lagi direkomendasikan untuk pengembangan baru karena TAP seharusnya menggantikannya (sumber).
Saya rasa saya memahami cara kerja async/await dan saya dapat menggunakannya untuk melakukan operasi IO yang memiliki metode async. Misalnya, saya dapat menulis metode async yang menunggu hasil GetStringAsync HttpWebClient, karena metode tersebut dinyatakan sebagai metode async. Itu hebat.
Pertanyaan saya adalah: bagaimana jika kita memiliki operasi IO yang terjadi pada metode yang tidak dinyatakan sebagai async? Seperti ini: misalkan saya memiliki API yang memiliki metode
string GetResultFromWeb()
yang menanyakan sesuatu dari Web. Dan saya mempunyai banyak pertanyaan berbeda yang harus dilakukan dan saya harus menggunakan metode ini untuk melakukannya. Dan kemudian saya perlu memproses setiap hasil kueri. Saya memahami bahwa saya akan melakukan ini jika itu adalah metode 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);
Namun karena tidak, saya tidak dapat menunggunya -- ini memberi tahu saya bahwa string tidak dapat ditunggu. Jadi pertanyaan saya adalah: apakah ada cara untuk melakukan operasi IO ini secara asinkron tanpa harus membuat satu utas untuk setiap kueri? Jika saya bisa, saya ingin membuat thread sesedikit mungkin, tanpa harus memblokir thread mana pun.
Salah satu cara yang saya temukan untuk melakukannya adalah dengan menerapkan APM, dengan mengikuti artikel ini dari Jeffrey Richter dan kemudian, dalam metode Begin saya, saya memanggil ThreadPool.QueueWorkItem(GetResultFromWeb, asyncResult). Seperti ini:
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();
}
}
Kemudian saya menggunakan AsyncEnumerator dan memulai (BeginQuery) beberapa kueri dan memproses hasilnya saat masing-masing kueri selesai (menggunakan pengembalian hasil/EndQuery). Hal ini tampaknya bekerja dengan baik. Tapi setelah membaca begitu banyak bahwa APM sudah usang, saya bertanya-tanya bagaimana saya bisa melakukan ini menggunakan TAP. Juga, apakah ada masalah dengan pendekatan APM ini?
Terima kasih!