我的實際程序比這更復雜,但我試圖簡化的東西。異步/等待和Task.Run - 如何知道什麼時候完成
因此,讓我們說我正在閱讀一個URL列表的文件。我想從每個URL下載HTML並處理它。處理過程可能有點複雜,所以我希望它在單獨的線程上完成。
基本問題是如何判斷何時完成所有處理。例如,如果用戶試圖在處理所有URL之前關閉該程序,我想給他一條消息而不是退出程序。或者,我希望在處理所有URL後終止程序(也許帶有MsgBox(「完成」)消息)。
我想我的代碼看起來如下(假設我有一個外循環讀取URL,並調用這個例程)...
List<Task> TaskList = new List<Task>();
async void ProcessSingleUrl(string url) {
var web = new HttpClient();
var WebPageContents = await web.GetStringAsync(url);
Task t = Task.Run(() => ProcessWebPage(WebPageContents);
TaskList.Add(t);
}
上面的代碼應該運行速度非常快(異步方法立即運行非常好),並立即返回給調用者。
但是在那個時候,我可能在TaskList中沒有任何條目,因爲在GetStringAsync完成之前沒有定義一個任務,並且當時沒有(或者只是幾個)完成。所以
Task.WaitAll(TaskList.ToArray());
不按我需要的方式工作。
如果絕對必要,我可以先閱讀所有網址,並知道需要多少任務,但我希望有一個更優雅的解決方案。
我想我可以在等待之前增加一個計數器,但這感覺有點遺憾。
我假設我正在構造錯誤的東西,但我不知道如何重組事情。
注意:我沒有執着於Task.Run。好的'QueueWorkItem是一種可能性,但我認爲它也有相同的問題。
在我看來,這是行不通的。 –
在我看來,這是行不通的。首先,你的意思是「迴歸t」而不是「等待」;? (沒有做任何事情後會「等待」什麼,對不對?)如果是這樣,我們不會回到我們開始的地方嗎?還是我錯過了一些東西(再次!)? –
@LarrySmith如果你遺漏了尾部,等待'ProcessSingleUrlInner'返回的任務將會在* ProcessWebPage完成之前完成。等待它「包含」ProcessWebPage到函數中。它確保'ProcessSingleUrlInner'在'ProcessWebPage'完成之前沒有完成。這就是這個解決方案的關鍵:你得到的任務只有在* everything *完成時才能完成。那是你想要的,對吧? – usr