Application hangs on wait async method [duplicate]

血红的双手。 提交于 2019-12-20 07:48:40

问题


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

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();

How can I fix this?

    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);
        }

    }

Output

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

Edited

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

Following @Frederik Gheysels advice did not help.

Output

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

回答1:


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

Here is an example how deadlock can happen

  1. async method called
  2. async method enters wait and main thread runs something else
  3. main thread executes a method calling wait()
  4. wait is waiting for async to finish
  5. async is waiting for main thread to become free
  6. DEAD LOCK

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




回答2:


You're experiencing a deadlock.

Why do you use .Wait() on that method call ?

You should make your calling method async and await the Task.

    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");
    }


来源:https://stackoverflow.com/questions/47312273/application-hangs-on-wait-async-method

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!