我想问您关于何时使用正确的体系结构的意见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 () => ... )
。使用async
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
}
await Task.Run(async () => await this.contentLoader.LoadContentAsync());
应该只是await Task.Run( () => this.contentLoader.LoadContentAsync() );
。AFAIK通过在里面加一秒await
并没有任何收获。而且由于您没有传递参数,因此可以简化到。async
Task.Run
await Task.Run( this.contentLoader.LoadContentAsync );