[英]Wait for Parallel Programming to Finish all tasks without freezing up GUI
我是.NET中所有並行編程范例的新手,我想知道兩件事:
我有一個private async Task RunTask(string task)
方法,該方法需要運行的次數與我擁有的任務數一樣多。
在一個private async void button_click(object sender, EventArgs e)
類中,我有一個名為tasklist
的字符串列表,該字符串列表初始化了我需要運行的任務。 我正在運行以下代碼:
Thread thread = new Thread(()=> Parallel.ForEach(tasklist, t => RunTask(t)));
thread.Start();
RunOnCompletionOfTasks();
我需要能夠利用我所有的CPU內核,並在盡可能短的時間內運行所有任務。 我認為Parallel.ForEach
是實現此目標的最佳方法,但我的任務也是async
因為它們的功能需要等待其他方法。 我的任務在執行期間還將一個字符串附加到類中的List<string>
對象上。
Parallel.ForEach
導致Windows窗體凍結,因此我將其封裝在線程中。 問題是RunOnComlpetionOfTasks();
在我的任務完成之前運行。
什么是最有效的辦法,我跑我所有的RunTask
任務,然后運行RunOnCompletionOfTasks
完成后,不會凍結了Windows窗體?
謝謝,麻煩您了。
如果您需要執行多個Tasks
(可以等待),那么Parallel.ForEach
可能不是最佳選擇。 它是專為CPU綁定進程而設計的,不支持async
操作。
您可以嘗試使用Task.WhenAll()
重寫代碼:
var tasks = tasklist.Select(RunTask);
// assuming RunTask is declared as `async Task`
await Task.WhenAll(tasks);
這樣,您就可以在方法調用中利用async
/ await
模式。
相反,如果您意識到自己的任務未正確async
(並且僅與CPU綁定),則可以嘗試在一個簡單的Task
執行Parallel.ForEach
await Task.Run(() => Parallel.ForEach(tasklist, RunTask);
// assuming RunTask is not `async Task`
首先,您需要區分並行和異步:
當您需要使用IO進行某些操作時,通常會玩。
當您需要對計算進行某些處理(例如存檔文件或圖像處理)時,通常會出現並行操作。
異步等待模式只是一個快捷方式,而不是靈丹妙葯。
如果您只需要並行計算,我建議使用TPL的並行人員(例如ParallelForEach),它們玩起來很酷,而且經過優化,非常好,以實現最高性能。
如果您嘗試執行一些IO操作,這可能是有道理的,但處理的數據量或多或少-如服務器應用程序。
您的處理器不能做的那么多
如果您的任務不是並行的,那么任何並行人員都無法為您提供幫助。 請注意,任何上下文切換都有一定的成本。 TaskSheduler將使用隊列來減少線程數,但它又做了一些工作。
線程新線程是邪惡的(至少在這里)。 您的處理器將更頻繁地切換到一個線程(更多線程-更多開關)
最后:當您不知道TPL的工作原理時,請不要使用它們。 只需使用您需要的類,就不要進行沒有真正優化的優化。
PS在UI中使用ContinueWith。 TPT中的任何內容都將返回具有此方法的任務,更新UI時請確保當前使用線程。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.