我想请你就何时使用Task.Run
的正确架构发表意见。我们的WPF .NET 4.5应用程序(使用Caliburn Micro框架)界面响应迟缓。
基本上,我的代码(非常简化的代码段)如下:
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 () => ... )
来包装它。使用async
await
不会阻塞UI,但仍在UI线程上运行,因此会使其卡顿。最佳放置Task.Run的位置是哪里?
我应该只是
- 包装外部调用,因为这对.NET来说是较少的线程工作,还是
- 仅在内部包装CPU绑定方法,使用
Task.Run
运行,因为这样可以使其在其他地方重复使用?我不确定在核心深处启动后台线程是否是一个好主意。
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
}
await Task.Run(async () => await this.contentLoader.LoadContentAsync());
可以简化为await Task.Run(() => this.contentLoader.LoadContentAsync());
。据我所知,在Task.Run
内部添加第二个await
和async
不会带来任何收益。由于您没有传递参数,因此可以进一步简化为await Task.Run(this.contentLoader.LoadContentAsync);
。 - ToolmakerSteveawait Task.Run(() => { RunAnySynchronousMethod(); return Task.CompletedTask; });
。 - Matt