【问题标题】:c# async without awaitc# 没有等待的异步
【发布时间】:2014-02-12 00:49:05
【问题描述】:

在此处的文档中:http://msdn.microsoft.com/en-us/library/hh191443.aspx 表示:

如果异步方法不使用 await 运算符来标记暂停 点,该方法像同步方法一样执行,尽管 异步修饰符。编译器会针对此类方法发出警告。

我相信这是警告:

此异步方法缺少“等待”运算符,将同步运行。 考虑使用 'await' 运算符来等待非阻塞 API 调用, 或 'await Task.Run(...)' 在后台线程上执行 CPU 密集型工作。

然后,在另一个引用的链接http://msdn.microsoft.com/en-us/library/windows/apps/hh994635.aspx 中,它显示的示例如下:

public class Example
{
    // ...
    private async void NextMove_Click(object sender, RoutedEventArgs e)
    {
        await Task.Run(() => ComputeNextMove());
        // Update the UI with results
    }

    private async Task ComputeNextMove()
    {
        // ...
    }
    // ...
}

在这里,我将假设ComputeNextMove 本身基本上是一个同步方法,而不是调用await。那么这似乎与编译器警告的发布相矛盾(除非它是一个坏例子......)

如果我没有在异步调用堆栈的 END 调用 .net Async 方法,例如 HttpClient.GetStringAsync 并且我确实想实现一些具体的“长时间运行”同步逻辑,是否有更合适的方法来做是吗?

也许我的假设不正确,ComputeNextMove 可以声明为 private void ComputeNextMove(),这样不会产生任何警告。

【问题讨论】:

  • 这令人困惑。你正在调用Task.Run(Func<Task>),它等待返回的任务。
  • Task 本身调用await。
  • “如果代码具有异步且没有等待,则它是同步的” - 显示两者的代码:“我假设它是同步的。”我迷路了。

标签: c# .net asynchronous async-await


【解决方案1】:

是的,这只是一个坏例子。

如果ComputeNextMove真正只是一个同步方法,它并没有真正异步地做任何事情(正如描述所暗示的那样),它不应该被声明为async。它应该是private void ComputeNextMove()。

由于使用了Task.Run,ComputeNextMove 仍将在后台线程上执行。

我很可能在这里使用方法组转换而不是 lambda 表达式:

await Task.Run((Action) ComputeNextMove);

【讨论】:

  • 感谢 Jon,这可能是一个非常愚蠢的问题,但我见过的大多数示例都显示了编写一个本质上调用 .net 异步方法的异步方法,我对 我可能想写一个这样的方法。根据响应(并以反编译 HttpClient.GetStringAsync 为例),它似乎归结为某处等待的任务。
  • @Novox:这并不总是一项任务,尽管它通常是。是的,很少有人会编写自己的“原始”异步方法。您通常最终会下降 - 可能通过许多其他异步方法 - 框架 *Async 方法...或为您不想在当前线程上执行的特定同步工作创建任务。
  • 在您的回答中,您使用了方法组覆盖而不是 Lamba 表达式。为什么这样 ?这样做有性能优势吗?
  • @BilalFazlani:不,只是简单一点。
猜你喜欢
  • 1970-01-01
  • 2021-04-15
  • 2015-09-28
  • 1970-01-01
  • 2012-08-12
  • 2017-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多