异步任务仍在阻塞UI线程
本文关键字:UI 线程 任务 异步 | 更新日期: 2023-09-27 17:58:01
我真的很想了解async/await
和Tasks
。我正试图找到一个方法,这样我就可以在整个程序中使用它。基本上,我有自己的BusyIndicator
版本,我想在工作完成时显示它。下面是一个基本的例子;
private async void OnPageLoad(object sender, RoutedEventArgs e)
{
var waitWindow = new PleaseWaitWindow();
waitWindow.Show();
await LoadCompanyContracts();
waitWindow.Close();
}
private async Task LoadCompanyContracts()
{
await Task.Run(() =>
{
Dispatcher.Invoke(() =>
{
//Work done here
});
});
}
即使通过这两种方法并尝试实现Tasks
,我的BusyIndicator
仍然没有旋转,它被显示但被冻结了,所以实际上我相信UI线程仍然被阻止。我如何修改这段代码以确保所有CPU绑定的工作都不会阻塞UI线程?
一般来说,根本不应该使用Dispatcher
。这是一种极为常见的做法,但却是一种普遍的不良做法。
private async Task LoadCompanyContracts()
{
await Task.Run(() =>
{
//Work done here
});
// Update UI if necessary.
}
不要在Dispatcher.Invoke()内工作,因为您的调度器与ui线程关联。在Task中完成工作,并仅使用调度器更新UI
private async Task LoadCompanyContracts()
{
await Task.Run(() =>
{
/*Work done here
*
*/
Dispatcher.Invoke(() =>
{
//Update UI
});
});
}
在这里的代码中查找了一些示例后,您可以尝试一个解决方案:
private async void OnPageLoad(object sender, RoutedEventArgs e)
{
var waitWindow = new PleaseWaitWindow();
waitWindow.Show();
InitLoadCompanyContracts();
waitWindow.Close();
}
private async void InitLoadCompanyContracts(){
await LoadCompanyContracts();
}
private async Task LoadCompanyContracts()
{
await Task.Run(() =>
{
Dispatcher.Invoke(() =>
{
//Work done here
});
});
}
我用这个有一个不可行的方法,但在所有的"图形"方法中。我不知道这是否是最好的方法,但对我来说,这是工作。