我想请教您对何时使用正确架构的看法Task.Run
。我在我们的 WPF .NET 4.5 应用程序(使用 Caliburn Micro 框架)中遇到了滞后的 UI。
基本上我在做(非常简化的代码片段):
public class PageViewModel : IHandle<SomeMessage>
{
...
public async void Handle(SomeMessage message)
{
ShowLoadingAnimation();
// Makes UI very laggy, but still not dead
await this.contentLoader.LoadContentAsync();
HideLoadingAnimation();
}
}
public class ContentLoader
{
public async Task LoadContentAsync()
{
await DoCpuBoundWorkAsync();
await DoIoBoundWorkAsync();
await DoCpuBoundWorkAsync();
// I am not really sure what all I can consider as CPU bound as slowing down the UI
await DoSomeOtherWorkAsync();
}
}
从我阅读/看到的文章/视频中,我知道它await
async
不一定在后台线程上运行,并且要在后台开始工作,您需要用 await 包装它Task.Run(async () => ... )
。Usingasync
await
不会阻塞 UI,但它仍然在 UI 线程上运行,所以它使它变得滞后。
放置 Task.Run 的最佳位置在哪里?
我应该只是
包装外部调用,因为这对 .NET 的线程工作较少
,或者我应该只包装内部运行的受 CPU 限制的方法,
Task.Run
因为这使它可以在其他地方重用?我不确定在核心深处的后台线程上开始工作是否是一个好主意。
广告(1),第一个解决方案是这样的:
public async void Handle(SomeMessage message)
{
ShowLoadingAnimation();
await Task.Run(async () => await this.contentLoader.LoadContentAsync());
HideLoadingAnimation();
}
// Other methods do not use Task.Run as everything regardless
// if I/O or CPU bound would now run in the background.
广告(2),第二种解决方案是这样的:
public async Task DoCpuBoundWorkAsync()
{
await Task.Run(() => {
// Do lot of work here
});
}
public async Task DoSomeOtherWorkAsync(
{
// I am not sure how to handle this methods -
// probably need to test one by one, if it is slowing down UI
}