gpt4 book ai didi

c# - ExecutionContext 不会从异步方法向上流动调用堆栈

转载 作者:太空狗 更新时间:2023-10-30 00:17:50 25 4
gpt4 key购买 nike

考虑以下代码:

private static async Task Main(string[] args)
{
await SetValueInAsyncMethod();
PrintValue();

await SetValueInNonAsyncMethod();
PrintValue();
}

private static readonly AsyncLocal<int> asyncLocal = new AsyncLocal<int>();

private static void PrintValue([CallerMemberName] string callingMemberName = "")
{
Console.WriteLine($"{callingMemberName}: {asyncLocal.Value}");
}

private static async Task SetValueInAsyncMethod()
{
asyncLocal.Value = 1;
PrintValue();

await Task.CompletedTask;
}

private static Task SetValueInNonAsyncMethod()
{
asyncLocal.Value = 2;
PrintValue();

return Task.CompletedTask;
}

如果您在 .NET 4.7.2 控制台应用程序中运行此代码,您将获得以下输出:

SetValueInAsyncMethod: 1
Main: 0
SetValueInNonAsyncMethod: 2
Main: 2

我明白输出的不同是因为 SetValueInAsyncMethod 实际上不是一个方法,而是由 AsyncTaskMethodBuilder 执行的状态机,它捕获 ExecutionContext 内部和 SetValueInNonAsyncMethod 只是一个常规方法。

但即使有了这样的理解,我仍然有一些问题:

  1. 这是错误/功能缺失还是有意设计的决定?
  2. 在编写依赖于 AsyncLocal 的代码时,我是否需要担心这种行为?比如说,我想编写我的 TransactionScope-wannabe,它可以通过等待点传输一些环境数据。 AsyncLocal 在这里够了吗?
  3. 当涉及到在整个过程中保留值时,.NET 中的 AsyncLocalCallContext.LogicalGetData/CallContext.LogicalSetData 是否还有其他替代方案“逻辑代码流”?

最佳答案

Is this a bug / missing feature or an intentional design decision?

这是一个有意的设计决定。具体来说,async状态机为其逻辑上下文设置“写入时复制”标志。

与此相关的是所有同步 方法都属于它们最近的祖先 async方法。

Do I need to worry about this behavior while writing code that depends on AsyncLocal? Say, I want to write my TransactionScope-wannabe that flows some ambient data though await points. Is AsyncLocal enough here?

像这样的大多数系统使用 AsyncLocal<T>结合 IDisposable清除 AsyncLocal<T> 的模式值(value)。组合这些模式可确保它适用于同步或异步代码。 AsyncLocal<T>如果消费代码是 async,它自己会正常工作方法;与 IDisposable 一起使用确保它适用于 async和同步方法。

Are there any other alternatives to AsyncLocal and CallContext.LogicalGetData / CallContext.LogicalSetData in .NET when it comes down to preserving values throughout the "logical code flow"?

没有。

关于c# - ExecutionContext 不会从异步方法向上流动调用堆栈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55480137/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com