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