我是C#中的異步編程新手,我仍然對一些事情感到困惑。 我已經讀過.NET 4.5之後,APM和EAP不再推薦用於新開發,因爲TAP應該替代它們(source)。是否可以等待未聲明爲異步的IO操作?如果不是,我該怎麼辦?
我想我理解async/await是如何工作的,我可以使用它們來執行具有異步方法的IO操作。例如,我可以編寫一個異步方法,等待HttpWebClient的GetStringAsync結果,因爲它被聲明爲異步方法。那很棒。
我的問題是:如果我們有一個IO操作發生在未聲明爲異步的方法中,該怎麼辦?是這樣的:假設我有一個有一個方法
string GetResultFromWeb()
哪些查詢從Web東西的API。而且我有很多不同的查詢要做,而我必須使用這樣做。然後我需要處理每個查詢結果。我明白我應該這樣做,如果這是一個異步方法:
Task<string> getResultTask = GetResultFromWeb(myUrl);
// Do whatever I need to do that doesn't need the query result
string result = await getResultTask;
Process(result);
但因爲它不是,我不能等待它 - 它告訴我的字符串不是awaitable。所以我的問題是:是否有任何方式異步執行這些IO操作,而不必爲每個查詢創建一個線程?如果可以的話,我想創建儘可能少的線程,而不必阻塞任何線程。
我發現這樣做的一種方法是通過執行APM,跟隨Jeffrey Richter的this article,然後在我的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方法有什麼問題嗎?
謝謝!
很好的回答!謝謝! –