应用程序挂起等待异步方法 [英] Application hangs on wait async method

查看:117
本文介绍了应用程序挂起等待异步方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的页面上有两个组合框控件,它们绑定到ObservableCollection< Vendor>.和ObservableCollection< Driver>.

I've got two combobox controls on my page, binded to a ObservableCollection<Vendor> and ObservableCollection<Driver>.

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

When the page is loaded the OnWindowLoaded() is executed. When the setter of the property Vendor is triggered, OnVendorPropertyChanged is executed. When OnWindowLoaded() finishes, Vendor and Driver is being set correctly.

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

However when I change the Vendor, the application waits on the line

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的建议无济于事.更改供应商时,应用程序仍会阻止.

Following Boo advice did not help. Application still blocks when changing vendor.

遵循@Frederik Gheysels的建议无济于事.

Following @Frederik Gheysels advice did not help.

输出

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

推荐答案

拥有异步方法后,您几乎再也不想调用wait.

You will almost never want to call wait when you have async methods.

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

Here is an example how deadlock can happen

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

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

so if it is possible, change the method where you are calling .wait() on to be async and call await on it

这篇关于应用程序挂起等待异步方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆