应用程序挂起等待异步方法

Application hangs on wait async method

我的页面上有两个组合框控件,绑定到 ObservableCollection 和 ObservableCollection

加载页面时,将执行 OnWindowLoaded()。 当属性 Vendor的setter被触发时,OnVendorPropertyChanged被执行。 当 OnWindowLoaded() 完成时,供应商和驱动程序设置正确。

但是,当我更改供应商时,应用程序会在线等待

LoadDriversAsync(Vendor.DCP).Wait();

我该如何解决这个问题?

    private async void OnWindowLoaded()
    {
        Debug.WriteLine("Enter OnWindowLoaded");
        await LoadVendorsAsync();
        await System.Threading.Tasks.Task.Run(() => { Vendor = Vendors.FirstOrDefault(); });
        await System.Threading.Tasks.Task.Run(() => { Driver = Drivers.FirstOrDefault(); });
        Debug.WriteLine("Leave OnWindowLoaded");
    }

     private Vendor _vendor;
     public Vendor Vendor
    {
        get
        {
            return _vendor;
        }

        set
        {
            if (value != _vendor)
            {
                var oldVendor = new Vendor();
                oldVendor = _vendor;
                _vendor = value;
                RaisePropertyChanged(nameof(Vendor), oldVendor, Vendor, true);
            }
        }
    }


    /// <summary>
    /// Raised when Vendor property is changed
    /// </summary>
    /// <param name="vendor"></param>
    private void OnVendorPropertyChanged(PropertyChangedMessage<Vendor> vendor)
    {
         Debug.WriteLine("Enter OnVendorPropertyChanged");

            //application hangs when vendor is changed
            LoadDriversAsync(Vendor.DCP).Wait();
            Debug.WriteLine("Leave OnVendorPropertyChanged");
    }

    private async System.Threading.Tasks.Task LoadVendorsAsync()
    {
            Debug.WriteLine("Enter LoadVendorsAsync");
            //load the vendors, don't return data
            Debug.WriteLine("Leave LoadVendorsAsync");

    }

      private Vendor _vendor;
    public Vendor Vendor
    {
        get
        {
            return _vendor;
        }

        set
        {
            if (value != _vendor)
            {
                var oldVendor = new Vendor();
                oldVendor = _vendor;
                _vendor = value;
                RaisePropertyChanged(nameof(Vendor), oldVendor, Vendor, true);
            }
        }
    }

   ObservableCollection<Vendor> _vendors = new ObservableCollection<Vendor>();
    public ObservableCollection<Vendor> Vendors
    {
        get
        {
            return _vendors;
        }

        set
        {
            if (_vendors != value)
            {
                var oldVendors = _vendors;
                _vendors = value;
                RaisePropertyChanged(nameof(Vendors), oldVendors, Vendors, true);
            }

        }
    }

private async System.Threading.Tasks.Tas LoadDriversAsync(Objects.Vendor Vendor)
    {

            Debug.WriteLine("Enter LoadDriversAsync");
//load data, don't return

            Debug.WriteLine("Leave LoadDriversAsync");
            RaisePropertyChanged(nameof(Drivers), oldDrivers, Drivers, true);
        }

    }

输出

Enter OnWindowLoaded
Enter LoadVendorsAsync
Leave LoadVendorsAsync
Enter OnVendorPropertyChanged
Enter LoadDriversAsync
Leave LoadDriversAsync
Leave OnVendorPropertyChanged
Leave OnWindowLoaded

已编辑

遵循 Boo 的建议没有帮助。更改供应商时应用程序仍然阻塞。

遵循@Frederik Gheysel 的建议没有帮助。

输出

Enter OnWindowLoaded
Enter LoadVendorsAsync
Enter OnVendorPropertyChanged
Enter LoadDriversAsync
Leave OnWindowLoaded
Leave LoadDriversAsync
Leave OnVendorPropertyChanged

您遇到了死锁。

为什么在该方法调用中使用 .Wait()?

您应该使调用方法异步并等待任务。

    private async void OnVendorPropertyChanged(PropertyChangedMessage<Vendor> vendor)
    {
         Debug.WriteLine("Enter OnVendorPropertyChanged");

         //application hangs when vendor is changed
         await LoadDriversAsync(Vendor.DCP);
         Debug.WriteLine("Leave OnVendorPropertyChanged");
    }

当你有异步方法时,你几乎永远不想调用 wait。

这是一个如何发生死锁的例子

  1. 调用了异步方法
  2. 异步方法进入等待状态,主线程运行其他东西
  3. 主线程执行一个调用wait()的方法
  4. wait 正在等待异步完成
  5. async 正在等待主线程空闲
  6. 死锁

因此,如果可能,请将调用 .wait() 的方法更改为异步并在其上调用 await