【发布时间】:2014-02-20 09:59:24
【问题描述】:
我需要尽可能快地不断执行 20 次重复的 CPU 密集型计算。所以有 20 个任务包含循环方法:
while(!token.IsCancellationRequested)
尽可能快地重复它们。所有计算同时进行。不幸的是,这使程序没有响应,所以补充说:
await Task.Delay(15);
此时程序没有挂起,但添加延迟不是正确的方法,它不必要地减慢了计算速度。它是没有 MVVM 的 WPF 程序。你建议用什么方法让所有 20 个任务同时工作?它们中的每一个都会在完成后不断重复。我想将 CPU(所有内核)利用率保持在最大值(或接近)以确保最佳效率。
编辑: 有 20 个控件,用户可以在其中调整一些参数。计算在:
private async Task Calculate()
{
Task task001 = null;
task001 = Task.Run(async () =>
{
while (!CTSFor_task001.IsCancellationRequested)
{
await Task.Delay(15);
await CPUIntensiveMethod();
}
}, CTSFor_task001.Token);
}
每个控件都是独立的。计算 100% 受 CPU 限制,没有 I/O 活动。 (所有值都来自变量)在计算过程中一些UI项目的值发生了变化:
this.Dispatcher.BeginInvoke(new Action(() =>
{
this.lbl_001.Content = "someString";
}));
【问题讨论】:
-
你能添加你目前使用的代码吗?因为 C#/WPF 中的多线程可以通过多种方式完成,而且您已经在谈论两种不同的机制(任务/并行)。
-
还有,有什么样的作品?工作项是否相关?它们真的 100% 受 CPU 限制,还是有 I/O 活动导致延迟?什么“挂”?用户界面?还是只有一些任务获得“公平”的 CPU 份额?你想要异步还是并行?
Task用于异步性,not 并行性,即。它旨在让您可以“同时”有效地运行许多不受 CPU 限制的操作,而无需额外线程的额外成本。 -
@BatteryBackupUnit 请不要手动更改线程优先级。只是不要。它不会做你认为它会做的事情。有关更多信息,请参阅codinghorror.com/blog/2006/08/thread-priorities-are-evil.html :) 另外,我希望 OP 实际上不会与 UI 并行运行工作:)
-
好的,所以你应该阅读一下
await+async。你显然认为他们做了他们没有做的事情。它们设计用于阻塞而不导致 CPU 使用的操作(通常等待某种 I/O)。它们不是神奇的“现在发生并行”关键字。您的方案根本不保证使用await/async。事实上,您的代码中发生的唯一正确异步的事情是await Task.Delay(15)位:) 您的代码还有一些问题,但这是问题的症结所在。 blog.stephencleary.com/2013/11/… -
@as74:我相信你会从使用 TPL 数据流库中受益。
标签: c# performance task delay