为什么AsyncLocal< T>代码稍微重构后会返回不同的结果? [英] Why does AsyncLocal<T> return different results when code is refactored slightly?

查看:49
本文介绍了为什么AsyncLocal< T>代码稍微重构后会返回不同的结果?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我调用 WrapperAsync AsyncLocalContext.Value 时,返回null.当我在方法外部运行相同的代码块时,在 Main 方法中, AsyncLocalContext.Value 不为null(这是我所期望的).

When I call WrapperAsync AsyncLocalContext.Value returns null. When I run the same code block outside the method, in the Main method, AsyncLocalContext.Value is not null (which is what I would expect).

功能完全相同,但结果有所不同.这是 Asynclocal 类的错误还是有其他解释?

The functionality is exactly the same yet the results are different. Is this a bug with the Asynclocal class or is there another explanation?

internal class Program
{
    private static readonly AsyncLocal<string> AsyncLocalContext = new AsyncLocal<string>();

    private static void Main()
    {
        const string text = "surprise!";

        WrapperAsync(text).Wait();
        Console.WriteLine("Get is null: " + (AsyncLocalContext.Value == null));
        // AsyncLocalContext.Value is null

        var value = GetValueAsync(text).Result;
        AsyncLocalContext.Value = value;
        Console.WriteLine("Get is null: " + (AsyncLocalContext.Value == null));
        // AsyncLocalContext.Value is not null
        Console.Read();
    }

    private static async Task WrapperAsync(string text)
    {
        var value = await GetValueAsync(text);
        AsyncLocalContext.Value = value;
    }

    private static async Task<string> GetValueAsync(string text)
    {
        await Task.Delay(0);
        return text;
    }
}

推荐答案

按照此链接

AsyncLocal< T> 表示对于给定的异步控制流(例如异步方法)本地的环境数据

AsyncLocal<T> represents ambient data that is local to a given asynchronous control flow, such as an asynchronous method

这意味着当您从另一个 async 方法(例如 WrapperAsync )访问并且您的主线程包含另一个值时,您的代码使用不同的值

It means that your code uses different values when it's accesses from another async method such as WrapperAsync and your main thread contains another value

[UPDATE]
没有明显的东西要理解,但是这里是解释.
控制流异步程序.当您不希望这样做时,这就是更改线程的方式.

[UPDATE]
Not obvious thing to understand, but here is explanation. Control Flow in Async Programs. This is how your thread is changed when you do not expect this.

这是控制流与 async

public class Program
{
    private static readonly AsyncLocal<string> AsyncLocalContext = new AsyncLocal<string>();

    public static void Main(string[] args)
    {
        AsyncLocalContext.Value = "No surprise";
        WrapperAsync("surprise!");
        Console.WriteLine("Main: " + AsyncLocalContext.Value);
    }

    private static async void WrapperAsync(string text)
    {
        Console.WriteLine("WrapperAsync before: " + AsyncLocalContext.Value);
        AsyncLocalContext.Value = text;
        Console.WriteLine("WrapperAsync after: " + AsyncLocalContext.Value);
    }
}

输出为:

WrapperAsync before: No surprise
WrapperAsync after: surprise!
Main: No surprise

[/UPDATE]

这篇关于为什么AsyncLocal&lt; T&gt;代码稍微重构后会返回不同的结果?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆