【问题标题】:Non-awaited async methods run on the UI thread?非等待异步方法在 UI 线程上运行?
【发布时间】:2015-10-08 22:17:52
【问题描述】:

我想要一个方法(我们称之为M1)在循环中执行一些async 代码(我们称之为第二个方法M2)。在每次迭代中 - UI 都应该使用 M2 的结果进行更新。

为了等待 M2M1 需要为 async。但是 M1 应该在 UI 线程上运行(以避免竞争条件),因此它会在没有 await 的情况下被调用。

我这样认为,M1对UI的更新会在UI线程上是对的吗?


额外:在这种情况下,async void 似乎没问题。这样对吗?)

【问题讨论】:

  • 是的,看来你是对的。试着去做吧。
  • 尝试会很棘手,因为在这种情况下通常不太可能出现竞争条件。我只是要小心,因为有人有时可能会遇到他们。
  • @ispiro 顺便说一句,如果你想尝试Task.Delay(10) 可能是创建真正异步方法的最简单方法。
  • @AlexeiLevenkov 感谢您的宝贵时间。我现在正在调查这整件事。如果它不在另一个线程上运行,我真的不明白异步有什么意义。无论如何,我现在正在阅读。再次感谢。

标签: c# .net multithreading asynchronous


【解决方案1】:

是的。 (假设您使用返回 UI 线程的同步上下文 - 即来自 WinForm/WPF 的线程)。

请注意,这也意味着您不能以这种方式安排 CPU 密集型操作,因为它将在 UI 线程上运行。

使用void async 是在 WinForms 中处理事件的标准方法:

void async click_RunManyAsync(...)
{
   await M1();
}

void async M1()
{
     foreach (...)
     {
        var result = await M2(); 
        uiElement.Text = result; 
     }
}

async Task<string> M2()
{
    // sync portion runs on UI thread
    // don't perform a lot of CPU-intensive work

    // off main thread, same synchronization context - so sync part will be on UI thread. 
    var result = await SomeReallyAsyncMethod(...); 

    // sync portion runs on UI thread
    // don't perform a lot of CPU-intensive work
}

【讨论】:

  • 谢谢。但我没有明确使用任何同步上下文,我在 UWP - Windows 通用应用程序中使用它。还可以吗?
  • 对,原理是一样的
  • 我不明白你的例子 - 因为等待 M1 - 它不会在 UI 线程上运行。不是这样吗?
  • @ispiro await 不会更改代码运行的线程同步部分 - 所以任何直到 await SomeReallyAsyncMethod 调用的东西都将在原始线程上。同步上下文决定异步操作结束后继续执行的位置。
  • @isipro,不,await 不会创建新线程(使用 UI 提供的同步上下文),除非您命令使用 await Task.Run(... cpu-bound code...) 手动创建它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-06-09
  • 1970-01-01
  • 2019-01-08
  • 1970-01-01
  • 2016-07-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多