【发布时间】:2022-02-11 07:10:35
【问题描述】:
在使用 dotTrace 分析使用 async/await 功能的应用程序时,我注意到父方法和子方法的 await 时间存在一些不一致。让我们考虑这个例子:
static async Task Main()
{
await ChildMethod();
}
static async Task ChildMethod()
{
await SomeOperationAsync();
}
有趣的是Main 方法的await 时间可能(甚至将)小于 await 时间@987654329 @ 这对我来说看起来很奇怪,因为直观上 await 父母的时间应该至少作为await 孩子的时间。
对于实数,让我们回到前面的例子,假设SomeOperationAsync 是Task.Delay(n)。因此,父级的await 时间将是x(x 是针对.NET 6.0 的应用程序的~n 和针对.NET Core 3.1 的应用程序的<n)和子级的await 时间将是~2*x。
这是来自 dotTrace 的屏幕截图,用于了解它的外观(针对面向 .NET Core 3.1 的应用和Task.Delay(800)):
- 这是
await方法Main的时间。 567ms 对于await ChildMethod(),我希望这是~800,因为ChildMethod等待Task.Delay(800) - 这是
await方法ChildMethod的时间。对于await Task.Delay(800),1140 毫秒。我也希望这是~800。
可能我误解了 dotTrace 中的 await 时间是什么,所以如果是,请纠正我。我将其理解为安排任务所需的时间 + 实际任务执行。
如果有人知道这种行为是否是预期的并能解释如何分析它,那就太好了。
我在 dotTrace 2021.3.3 中使用时间线查看器。
更新
我想我理解了我困惑的第一部分,即为什么 await 时间小于 Main 方法中传递给 Task.Delay 的时间。这是因为任务的计时器比继续附加(内部调用AwaitUnsafeOnCompleted)更早开始,因此它只等待剩余时间。在我的情况下,这个调用大约需要 300ms,因此 await 时间变为 time passed to Task.Delay - time spent on attaching continuation。
【问题讨论】:
标签: c# async-await profiling jetbrains-ide dottrace