【问题标题】:Using "await" in Dispatcher.RunAsync() throws an exception在 Dispatcher.RunAsync() 中使用“await”会引发异常
【发布时间】:2013-07-01 14:26:12
【问题描述】:

相关代码如下:

Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>
{
    MessageDialog dialog = new MessageDialog("Wrong username or passwork. Please try again.");
    await dialog.ShowAsync();
    this.LoginButton.IsEnabled = true;
});

当我运行它时,会抛出 E_ACCESSDENIED。

这里允许异步等待吗?

【问题讨论】:

  • 堆栈跟踪是什么?
  • 您确定是await 导致访问被拒绝吗?您是否尝试过用dialog.Show(); 替换await dialog.ShowAsync(); 看看是否可行?
  • @Sean WinRT 中没有非异步的Dialog.Show() 方法。
  • @dlev 糟糕,我没有正确阅读标签。好吧,我已经超出了我的深度^_^
  • @Lucas 上帝。太感谢了!我应该犯这么愚蠢的错误。

标签: c# .net asynchronous windows-8 microsoft-metro


【解决方案1】:

Dispatcher.RunAsync 并非设计用于接受async 委托。它被设计为自己返回一个Task,以便可以等待它。你给它的方法应该是非异步方法。

它接受的委托的实际签名是public delegate void DispatchedHandler()

因为返回RunAsync 的委托无效,所以第一次awaits 时会认为它已经完成,而不是在它实际完成时。这意味着等待此方法的任何代码都将继续执行。

【讨论】:

  • 我认为这有点误导。:( 编译器允许在运行时执行异步操作失败。嗯,我使用 Dispatcher 是因为它在 TextBox 的 KeyDown 事件处理程序时抛出 E_ACCESSDENIED 异常,这调用await dialog.ShowAsync(),被调用了,不是和主UI在同一个线程吗?为什么action被拒绝?
  • @IsilmëOrphousV 这就是为什么你需要警惕async void 方法的原因。编译器必须允许它,即使它通常不合适。至于错误,我只能说这段代码没有做它应该做的事情,但是没有足够的代码显示出来,具体来说,这里出了什么问题。也许RunAsync,因为它认为它已经完成,不会保持它的当前上下文处于活动状态,或者它根本没有设置当前同步上下文,我不确定。无论如何,这似乎不是正确使用RunAsync
  • 查看这个关于等待实际工作完成的问题:stackoverflow.com/questions/19133660/…
猜你喜欢
  • 2013-03-30
  • 2021-07-18
  • 1970-01-01
  • 2018-07-10
  • 2012-12-07
  • 2013-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多