【问题标题】:Return async result to an event将异步结果返回给事件
【发布时间】:2013-07-19 05:34:42
【问题描述】:

假设我有一个 API 事件,我必须返回一个结果。 我必须做的计算使用异步方法,它创建一个控件(必须在 UI 线程上运行)。

private async void API_QueryControl(object sender, APIEventArgs e)
{
e.Result = await CreateControl();
}

private async Task<Control> CreateControl()
{
await Task.Delay(1000);
return new Panel();
}

现在,这显然行不通,因为 API_QueryControl 在我设置结果之前就产生了。我无法控制 API,这意味着无法更改事件。如何让事件等待结果?

【问题讨论】:

  • 你没有。您可以阻止 UI 线程、更改或不使用该方法、找到更快的方法来计算值等。
  • 如何通过阻塞 UI 线程使其工作? CreateControl().Result、CreateControl().Wait() 等导致死锁。
  • 在这种情况下阻止 UI 线程的一种方法是不使用异步... ;-)

标签: c# events asynchronous return


【解决方案1】:

您可以使用ConfigureAwait(false) 阻止当前(UI)线程,但避免死锁。像这样:

e.Result = await CreateControl().ConfigureAwait(false);

ConfigureAwait(false) 使 CreateControl 的延续部分 - await Task.Delay 之后的部分 - 在线程池而不是原始 UI 线程上运行。

我假设您有一些理由使用这样的异步,而不是仅仅编写 CreateControl 的同步版本。这不仅是更简单的代码,它还将使用原始 (UI) 线程来完成工作,而不是在 UI 线程等待它时使用第二个线程。

还请注意,您应始终防止从 async void 方法引发异常 - 请参阅已接受的答案 here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-02
    • 1970-01-01
    • 1970-01-01
    • 2010-11-19
    • 1970-01-01
    • 1970-01-01
    • 2017-07-02
    • 2014-07-20
    相关资源
    最近更新 更多