C# 等待并行编程完成所有任务,而不冻结GUI
我不熟悉.NET中的所有并行编程范例,我想知道两件事:C# 等待并行编程完成所有任务,而不冻结GUI,c#,.net,multithreading,parallel-processing,C#,.net,Multithreading,Parallel Processing,我不熟悉.NET中的所有并行编程范例,我想知道两件事: 我如何等待所有任务完成运行而不冻结主窗体 我解决以下问题的方法是最好的方法吗 我有一个private async Task RunTask(string Task)方法,我需要将它运行的次数与我拥有的任务数量相同 在一个private async void按钮\u click(object sender,EventArgs e)类中,我有一个名为tasklist的字符串列表,它初始化了我需要运行的任务。我正在运行以下代码: Thread t
private async Task RunTask(string Task)
方法,我需要将它运行的次数与我拥有的任务数量相同
在一个private async void按钮\u click(object sender,EventArgs e)
类中,我有一个名为tasklist
的字符串列表,它初始化了我需要运行的任务。我正在运行以下代码:
Thread thread = new Thread(()=> Parallel.ForEach(tasklist, t => RunTask(t)));
thread.Start();
RunOnCompletionOfTasks();
我需要能够利用我所有的CPU核心,并在尽可能短的时间内运行所有任务。我认为Parallel.ForEach
是实现这一点的最佳方式,但我的任务也是async
,因为它们的函数需要等待其他方法。我的任务在执行过程中还会向类中的列表
对象追加一个字符串
Parallel.ForEach
导致我的Windows窗体冻结,因此我将其封装在一个线程中。这方面的问题是RunOnComlpetionOfTasks()代码>在我的任务完成之前运行
对于我来说,运行所有RunTask
任务,然后在完成后运行runoncompletionoftask
而不冻结Windows窗体的最有效方法是什么
请并感谢您。如果您需要执行多个任务
(正在等待),则并行执行。ForEach
可能不是最佳选择。它真正是为CPU限制的进程而设计的,不支持async
操作
您可以尝试使用任务重写代码。WhenAll()
:
通过这种方式,您可以在方法调用中利用async
/wait
模式
相反,如果您意识到您的任务不是正确的异步
(并且仅限于CPU),您可以尝试在简单的任务中执行并行.ForEach
await Task.Run(() => Parallel.ForEach(tasklist, RunTask);
// assuming RunTask is not `async Task`
如果您需要执行多个任务
(可等待),那么并行。ForEach
可能不是最佳选择。它真正是为CPU限制的进程而设计的,不支持async
操作
您可以尝试使用任务重写代码。WhenAll()
:
通过这种方式,您可以在方法调用中利用async
/wait
模式
相反,如果您意识到您的任务不是正确的异步
(并且仅限于CPU),您可以尝试在简单的任务中执行并行.ForEach
await Task.Run(() => Parallel.ForEach(tasklist, RunTask);
// assuming RunTask is not `async Task`
首先,您需要区分并行和异步:
当您需要使用IO执行某些操作时,异步通常是播放
当您需要处理计算(如归档文件)时
(或图像处理)是并行的东西,通常会发挥作用
异步等待模式它只是一种快捷方式,而不是银弹。
如果你只需要并行你的计算,我建议使用来自TPL的并行人员,比如ParallelForEach,他们很酷,经过优化,可以获得最大的性能
如果您试图执行一些IO操作,这是有意义的,但或多或少需要处理大量数据,比如服务器应用程序
你的处理器不能做更多的事情
如果你的任务不是平行的,任何平行的工作人员都不能帮助你。
请注意,任何上下文切换都有一定的代价。
TaskScheduler将使用队列来减少线程数,但它会再次执行一些工作
线程新线程是邪恶的(至少在这里)。您的处理器将更频繁地切换到一个或多个线程(更多线程-更多交换机)
最后:
当你不知道事情是如何运作的时候,尽量不要使用第三方物流。只要使用你需要的类,不要做那些没有真正优化的优化
PS
在UI中使用ContinueWith。TPT中的任何内容都将返回具有此方法的任务,
更新UI请确保您当前所在的线程。首先,您需要区分并行和异步:
当您需要使用IO执行某些操作时,异步通常是播放
当您需要处理计算(如归档文件)时
(或图像处理)是并行的东西,通常会发挥作用
异步等待模式它只是一种快捷方式,而不是银弹。
如果你只需要并行你的计算,我建议使用来自TPL的并行人员,比如ParallelForEach,他们很酷,经过优化,可以获得最大的性能
如果您试图执行一些IO操作,这是有意义的,但或多或少需要处理大量数据,比如服务器应用程序
你的处理器不能做更多的事情
如果你的任务不是平行的,任何平行的工作人员都不能帮助你。
请注意,任何上下文切换都有一定的代价。
TaskScheduler将使用队列来减少线程数,但它会再次执行一些工作
线程新线程是邪恶的(至少在这里)。您的处理器将更频繁地切换到一个或多个线程(更多线程-更多交换机)
最后:
当你不知道事情是如何运作的时候,尽量不要使用第三方物流。只要使用你需要的类,不要做那些没有真正优化的优化
PS
在UI中使用ContinueWith。TPT中的任何内容都将返回具有此方法的任务,
更新UI请确保您当前所在的线程。我想您正在寻找等待任务。Whalll
我想您正在寻找等待任务。Whalll
谢谢<代码>任务。当所有的
看起来都相当有效。我还是,呵呵