异步任务仍在阻塞UI线程

本文关键字:UI 线程 任务 异步 | 更新日期: 2023-09-27 17:58:01

我真的很想了解async/awaitTasks。我正试图找到一个方法,这样我就可以在整个程序中使用它。基本上,我有自己的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线程?

异步任务仍在阻塞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
            });
        });     
    }

我用这个有一个不可行的方法,但在所有的"图形"方法中。我不知道这是否是最好的方法,但对我来说,这是工作。