找到你要的答案

Q:Application dispatcher invoke freezes the application

Q:应用程序调用冻结应用程序

I am having problem with the application freezing. Let me explain my scenario, I have a service which does an async call to a database to get a list of items, It is run by a task. Inside this task I have a try catch block, so it looks like this

public Task<List<T>> ComboListAsync(int? id = null, EnumDTO dto = EnumDTO.Default)
    {
        return Task.Run(() =>
        {
            using (var context = new ContextService())
            {
                try
                {
                    return GetComboList(id, dto, context);
                }
                catch (Exception e)
                {
                    Handler.DatabaseConnectionException();
                    throw;
                }
            }
        });
    }

Then it throws an exception as GetComboList its just this (for the moment)

    protected virtual List<T> GetComboList(int? id, EnumDTO dto, ContextService context)
    {
        throw new NotImplementedException();
    }

So the call catches the exception and goes inside here

    public void Show(string message)
    {
        Message = message;
        Application.Current.Dispatcher.Invoke(() =>
        {
            dialogView = new DialogView() {DataContext = this, Owner = Application.Current.MainWindow};
            dialogView.ShowDialog();
        });
    }

Now the Dispatcher freezes the app, I tried to change it to use begin invoke, it does the same. Without the dispatcher I get an error message that the calling thread is not a STA. I simply want to display my message in a dialog window, that there was a problem connecting to a database. Can anyone help? I looked online and there is many threads about dispatcher, but none actually show a solution that will fix my issue.

Thank you

EDIT Code which calls the ComboListAsync

    protected override void RetrieveRelatedActiveLists()
    {
        MyCollection = service.ComboListAsync().Result;
    }

我有申请冻结的问题。让我解释我的情况,我有一个服务,并通过异步调用数据库得到的物品清单,它是由一个任务。在这个任务里面我有一个尝试捕捉块,所以它看起来像这样

public Task<List<T>> ComboListAsync(int? id = null, EnumDTO dto = EnumDTO.Default)
    {
        return Task.Run(() =>
        {
            using (var context = new ContextService())
            {
                try
                {
                    return GetComboList(id, dto, context);
                }
                catch (Exception e)
                {
                    Handler.DatabaseConnectionException();
                    throw;
                }
            }
        });
    }

然后,它抛出一个异常getcombolist只是(暂时)

    protected virtual List<T> GetComboList(int? id, EnumDTO dto, ContextService context)
    {
        throw new NotImplementedException();
    }

因此,呼叫捕获异常,并在这里

    public void Show(string message)
    {
        Message = message;
        Application.Current.Dispatcher.Invoke(() =>
        {
            dialogView = new DialogView() {DataContext = this, Owner = Application.Current.MainWindow};
            dialogView.ShowDialog();
        });
    }

Now the Dispatcher freezes the app, I tried to change it to use begin invoke, it does the same. Without the dispatcher I get an error message that the calling thread is not a STA. I simply want to display my message in a dialog window, that there was a problem connecting to a database. Can anyone help? I looked online and there is many threads about dispatcher, but none actually show a solution that will fix my issue.

谢谢你

EDIT Code which calls the ComboListAsync

    protected override void RetrieveRelatedActiveLists()
    {
        MyCollection = service.ComboListAsync().Result;
    }
answer1: 回答1:

Its a deadlock because of the calling code is using the .Result.

Using service.ComboListAsync().Result makes the UI thread await for this method to return, when you call Application.Current.Dispatcher.Invoke from within it you are sending a message to the UI thread that is awaiting the return of method itself.

You must await the method service.ComboListAsync() like this:

  protected override async void RetrieveRelatedActiveLists()
  {
      MyCollection = await service.ComboListAsync();
  }

因为调用代码正在使用结果,所以死锁。

使用服务。combolistasync()。结果使UI线程等待该方法返回,当你打电话application.current.dispatcher.invoke在你发送一个消息给UI线程正在等待方法本身的回归。

你必须等待的方法combolistasync()这样的服务:

  protected override async void RetrieveRelatedActiveLists()
  {
      MyCollection = await service.ComboListAsync();
  }
wpf  multithreading  messagebox  dispatcher