c# - 什么会导致标有 async 的方法同步执行,即使它包含 await 调用?

标签 c# async-ctp

我正在尝试调试我的同事在他离开时编写的一些代码。

电话如下:

var sw = Stopwatch.StartNew();
logger.Trace("Time A: {0}ms", sw.ElapsedMilliseconds); // Roughly 0ms
pt.Task = ProcessMetricsWorker(pt.CancelTokenSource);
sw.Stop();
logger.Trace("Time B: {0}ms", sw.ElapsedMilliseconds); // Over 20000ms!

这是方法签名:

async Task ProcessMetricsWorker(CancellationTokenSource cancelTokenSource)

该方法需要大约 20 秒才能运行,根据我在上面引用的第一行之前和之后放置的日志记录,该任务正在同步执行,就好像 async 部分被忽略一样。什么会导致这种情况发生?

请注意,异步方法内有一个 await 调用。它位于 while 循环内,尽管我无法想象这会产生影响。

// internal to the method referenced above
result = await metricProcessor.ProcessItem(domain);

此外,我创建了一个小型测试应用程序,它运行一个非常简单的异步/等待设置,以确保等待实际上在我运行它的服务器上工作,并且它在我的小测试用例中确实工作正常,只是不正确在我正在尝试调试的主应用程序中。

最佳答案

每个async方法作为常规方法调用启动。它仅在第一次执行 await 时才变为异步(在屈服于其调用者的意义上)。等待(尚未完成)。

因此,ProcessMetricsWorker 中发生的情况有几种可能性:

  • 它可能在第一个 await 之前包含一些长时间运行的同步代码。 .
  • 许多第一个等待的事情是 await s 可能已经完成。如果它们全部已完成,则 ProcessMetricsWorker实际上是同步的。

“快速路径”blog post包含有关如何 await 的更多详细信息被转换为代码,并显示它如何仅在作用于未完成的等待时产生。

关于c# - 什么会导致标有 async 的方法同步执行,即使它包含 await 调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8753282/

相关文章:

c# - 从现有对象创建代理

c# - await 立即移动到下一条语句

c# - 将异步 CTP 与可移植类库一起使用

c# - 异步 CTP 在 VS 2010 SP1 中不起作用?

visual-studio-2010 - 安装 Visual Studio Async CTP 不起作用

c# - 有没有办法告诉 Resharper 6 忽略新的异步语言功能?

c# - 如何下载没有特定内容类型的文件

c# - LINQ Join 仅适用于 Orderby

c# - 使用 LINQ 选择本周

c# - 通过数据网格将数据保存到数据库