我正在做一个小项目。我需要实现某种算法,在大多数情况下会占用大量的CPU资源,因此需要一些时间来执行和返回。我希望这种方法能够响应并通知任何进展。我可能还想在进行这些计算时执行其他一些过程。
考虑这个具有复杂方法的类
class Engine
{
public int ComplexMethod(int arg)
{
int result = 0;
for (int i = 0; i < 100000; i++)
{
for (int j = 0; j < 10000; j++)
{
// some complex and time-consuming computations
}
// it would be nice to get notified on arriving this point for example
}
return result;
}
}
这种情况的最佳方法是什么?
编辑:我应该提到它是一个带有UI(WPF应用程序)的应用程序。答案 0 :(得分:8)
您可以使用Task.Run
在新线程中运行该进程,并使用IProgress<T>
接口通知进度:
class Engine
{
public int ComplexMethod(int arg, IProgress<double> progress)
{
int result = 0;
for (int i = 0; i < 100000; i++)
{
for (int j = 0; j < 10000; j++)
{
// some complex and time-consuming computations
}
progress.Report(i / 100000);
}
return result;
}
}
...
var progress = new Progress<double>(p => ShowProgress(p));
var result = await Task.Run(() => engine.ComplexMethod(arg, progress));
ShowResult(result);
如果您有UI(很可能),将使用Control.Invoke
(Windows窗体)或Dispatcher.Invoke
(WPF,WinRT,Silverlight)在UI线程上自动调用渐进委托,只要在UI线程上创建了Progress<T>
实例。
请注意,如果计算受CPU限制,async/await
将无法帮助(在方法内部)。但是,它可以用来更容易检索结果,如上所示。如果由于某种原因您不能或不想使用await
,则可以使用ContinueWith
,为TaskScheduler.FromCurrentSynchronizationContext
参数指定scheduler
。
答案 1 :(得分:0)
假设您使用的是.NET 4.5(C#5),则可以使用TPL
(http://msdn.microsoft.com/en-us/library/dd997423(v=vs.110).aspx)。
由于不了解您的算法,我所能建议的是您返回Task<int>
而不是返回int
。这将允许该功能与其他任务并行运行。
我会推荐以下内容:
public Task<int> ComplexMethodAsync(int arg)
{
Task.Run(()=>ComplextMethod(arg));
}
现在,当您运行此方法时,ComplexMethod(arg)
将在ThreadPool
的单独线程上调用。称之为:
await ComplextMethodAsync(xyz);
查看async/await了解详情。