我第一次使用Parallel.ForEach
,我正在处理文件;在WinForms应用程序的上下文中。
根据其他线程对此编码问题的指导(Parallel.ForEach进度报告)我的类上有一个public(int)计数器属性,它包含并行代码,并且它已成功更新;我的表格上还有一个定时读取计数器的计时器。
问题在于,当我执行并行代码时,可见进度更新似乎停止,然后在并行代码完成后立即启动。
仅供参考 - 我直接调用并行代码 - 也就是说,不是通过后台工作程序或异步方法。
答案 0 :(得分:4)
Parallel.ForEach
实际上以并行方式评估查询,但确实等待执行完成并阻塞调用线程。
您应该在单独的线程/后台工作/任务上使用它来更新进度变量,同时不阻止UI。
答案 1 :(得分:1)
如果从UI线程调用Parallel.ForEach()
(缺少代码示例,我们无法确切知道发生了什么),那么该方法停止并等待所有处理完成的事实将阻止您的UI线程执行任何其他工作,包括a)允许处理计时器事件,以及b)即使处理完计时器也允许更新UI。
一种可能的方法是将Parallel.ForEach()
的电话打包到Task.Run()
。例如:
private async void button1_Click(object sender, EventArgs e)
{
// some stuff
await Task.Run(() => Parallel.ForEach(...));
// some other stuff
}
或者,您可以将整个事务作为单独的任务执行:
private async void button1_Click(object sender, EventArgs e)
{
// some stuff
List<Task> tasks = new List<Task>();
foreach (...)
{
tasks.Add(Task.Run(() => ...));
}
await Task.WhenAll(tasks);
// some other stuff
}
(上面的例子省略了具体细节,因为在问题中没有代码示例,就无法知道实际会发生什么)。
任何一种方法都应该释放你的UI线程,以便在处理过程中处理进度更新。