我正在尝试调试我的同事在他离开时编写的一些代码。
电话如下:
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/