Cau*_*tix 1 c# parallel-processing asynchronous task-parallel-library
我有一个单线程程序,它执行复杂,耗时的计算并报告这些程序的进度.
private void BtnExecute_Click()
{
ComplexCalculation(Object1);
ComplexCalculation(Object2);
ComplexCalculation(Object3);
}
Run Code Online (Sandbox Code Playgroud)
ComplexCalculation方法如下所示:
private void ComplexCalculation(Object MyObject)
{
(...do some time consuming operation on MyObject...);
WriteToTextboxGUI("50% Complete" + MyObject.Name);
(...do another time consuming operation on MyObject...);
WriteToTextboxGUI("100% Complete" + MyObject.Name);
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,该WriteToTextboxGUI(string)方法使用进度更新GUI上的文本框.
我正在寻求采用多线程方法,以便在执行复杂计算时GUI保持响应.我已经阅读了相当多的内容BackgroundWorker,Threads一般情况下,以及当TaskTPL与.Net 4.0一起进入现场时如何简化/改进,现在如何Async和Await已经到达.Net 4.5,并想知道这些是否更新的技术可以让我重新编写我的应用程序(使用相对简单的代码),以便它可以:
任何人都可以指出一个满足这三个标准的简单解决方案吗?
PS此应用程序不会在服务器上运行,它将在桌面上的WPF中运行.
我建议您使用IProgress<T>进度报告并Task.Run启动后台任务.我最近完成了一个博客系列,显示Task.Run优于BackgroundWorker.
在你的情况下:
private sealed class ComplexCalculationProgress
{
public string Name { get; set; }
public int PercentComplete { get; set; }
}
private void ComplexCalculation(Object MyObject, IProgress<ComplexCalculationProgress> progress)
{
(...do some time consuming operation on MyObject...);
if (progress != null)
progress.Report(new ComplexCalculationProgress { Name = MyObject.Name, PercentComplete = 50 });
(...do another time consuming operation on MyObject...);
if (progress != null)
progress.Report(new ComplexCalculationProgress { Name = MyObject.Name, PercentComplete = 100 });
}
Run Code Online (Sandbox Code Playgroud)
请注意,由于您的后台操作不再调用WriteToTextboxGUI,因此可以更好地分离关注点.您会发现,IProgress<T>设计可以在您自己的代码中鼓励更好的设计.
你可以这样称呼它(使用简单的并行性):
private async void BtnExecute_Click()
{
var progress = new Progress<ComplexCalculationProgress>(update =>
{
WriteToTextboxGUI(update.PercentComplete + "% Complete " + update.Name);
});
await Task.WhenAll(
Task.Run(() => ComplexCalculation(Object1, progress)),
Task.Run(() => ComplexCalculation(Object2, progress)),
Task.Run(() => ComplexCalculation(Object3, progress))
);
}
Run Code Online (Sandbox Code Playgroud)
或者,您可以轻松使用"真正的"并行性:
private async void BtnExecute_Click()
{
var progress = new Progress<ComplexCalculationProgress>(update =>
{
WriteToTextboxGUI(update.PercentComplete + "% Complete " + update.Name);
});
var objects = new[] { Object1, Object2, Object3 };
await Task.Run(() =>
Parallel.ForEach(objects, o => ComplexCalculation(o, progress))
);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1018 次 |
| 最近记录: |