Wpf Application dispatcher invoke冻结应用程序
我对应用程序冻结有问题。让我解释一下我的场景,我有一个对数据库进行异步调用以获取项目列表的服务,它由一个任务运行。在这个任务中,我有一个try-catch块,所以看起来像这样Wpf Application dispatcher invoke冻结应用程序,wpf,multithreading,messagebox,dispatcher,Wpf,Multithreading,Messagebox,Dispatcher,我对应用程序冻结有问题。让我解释一下我的场景,我有一个对数据库进行异步调用以获取项目列表的服务,它由一个任务运行。在这个任务中,我有一个try-catch块,所以看起来像这样 public Task<List<T>> ComboListAsync(int? id = null, EnumDTO dto = EnumDTO.Default) { return Task.Run(() => { using
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;
}
}
});
}
现在Dispatcher冻结了应用程序,我尝试将其更改为使用begin invoke,它也会这样做。如果没有dispatcher,我会收到一条错误消息,表明调用线程不是STA。我只想在对话框窗口中显示我的消息,即连接到数据库时出现问题。有人能帮忙吗?
我在线查看了一下,发现有很多关于dispatcher的帖子,但实际上没有一个能解决我的问题的解决方案
多谢各位
编辑
调用ComboListAsync的代码
protected override void RetrieveRelatedActiveLists()
{
MyCollection = service.ComboListAsync().Result;
}
这是一个死锁,因为调用代码正在使用
.Result
当您调用Application.Current.Dispatcher.Invoke
时,使用service.ComboListAsync().Result
会使UI线程等待此方法返回,您将从其中向等待方法本身返回的UI线程发送消息
您必须等待方法service.ComboListAsync()
,如下所示:
protected override async void RetrieveRelatedActiveLists()
{
MyCollection = await service.ComboListAsync();
}
如果在
Show()
方法中放置断点,是否会命中它?在Invoke()内部呢?另外,您是否可以发布调用ComboListAsnyc()
和Show()
的代码?必须是上述方法调用的一部分,它可以正常工作me@AndrewStephens点击了节目,它进入了Application.Current.Dispatcher行。此时,它返回到UI,它冻结了。非常感谢,这就解决了它。我不明白的是为什么会发生这种情况,我认为结果实际上会调用await。事实并非如此,结果会阻塞线程,直到函数返回为止,将其视为sync waiting。另一方面,await关键字让线程运行并设置一个“bookmark”,当方法返回时,它将从书签点继续。这是一个异步等待。从技术上讲,它比那更复杂。喝杯咖啡,从这里开始:非常感谢您抽出时间。我一定会读的。wait有一点我不喜欢,它会继续运行代码,不会冻结,但是在这个方法之后,MyCollection会立即被访问,并抛出null引用异常,而结果是,它会返回到UI显示一些动画,并在准备继续时显示。所以我猜使用MyCollection的代码也需要是异步的,但是使用MyCollection的代码也需要是异步的,所以最后所有的东西都必须是异步的,因为一个方法依赖于另一个。是的,async/await一直都是异步的。但如果你仔细想想,这是有道理的(为什么你想冻结用户界面)。一个选项是使用任务延续,比如:service.ComboListAsync().ContinueWith(/*UpdateUI here*/),但我认为这里的更多细节是非常丑陋的()。。。还有另一种方法,但这将完全改变您的代码,这是一个全新的世界。它名为RxFramework(),再次感谢您的回复,我想我只需要比最初想象的更深入地研究它:)
protected override void RetrieveRelatedActiveLists()
{
MyCollection = service.ComboListAsync().Result;
}
protected override async void RetrieveRelatedActiveLists()
{
MyCollection = await service.ComboListAsync();
}