首页 > 其他分享 >.Net AsyncLocal介绍

.Net AsyncLocal介绍

时间:2023-08-15 20:11:27浏览次数:30  
标签:Console Name ctx 介绍 AsyncLocal public Net Id

AsyncLocal的基本概念

AsyncLocal是一个在异步环境中存储和传递状态的类型。它允许你在线程或任务之间共享数据,而不会受到异步上下文切换的影响。

每一个异步的AsyncLocal的数据都是独立的

  • AsyncLocal主要是用来在同一个异步控制流内共享对象的,如:一个web请求经过多个 async/await 方法调用后(可能切换了多个线程)依然可以共享同一个对象;
  • AsyncLocal存在层级嵌套的特点,不像ThreadLocal一个线程到底,也就是说AsyncLocal是工作在树形的异步控制流上的;
    class Program
    {
        private static AsyncLocal<WebContext> threadLocal = new AsyncLocal<WebContext>();
        static void Main(string[] args)
        {
            //模拟5个HTTP请求
            for (var i = 0; i < 5; i++)
            {
                var index = i;
                Task.Factory.StartNew(async () =>
                {
                    var ctx = threadLocal.Value = new WebContext();
                    ctx.Name = "请求" + index;
                    ctx.Id = index;
                    Console.WriteLine($"Delay前 线程ID:{Thread.CurrentThread.ManagedThreadId} ctx.Name={ctx.Name} ctx.Id={ctx.Id}");
                    await Task.Delay(new Random().Next(1000, 2000));
                    Console.WriteLine($"Delay后 线程ID:{Thread.CurrentThread.ManagedThreadId} ctx.Name={ctx.Name} ctx.Id={ctx.Id}");
                });
            }
            Console.Read();
        }
    }

    class WebContext
    {
        public string Name { get; set; }
        public int Id { get; set; }
    }

image

AsyncLocal在树形异步控制流上流动的特点:

  • 每个节点都可以有自己的对象;
  • 当子节点没有设置对象时,则访问的是父节点的对象;
  • 当子节点设置了对象时,则访问自己设置的对象;
  • 父节点无法访问子节点设置的对象;
    class Program
    {
        private static AsyncLocal<WebContext> asyncLocal = new AsyncLocal<WebContext>();
        static async Task Main(string[] args)
        {
            await Async();
            Console.Read();
        }

        //父上下文
        public static async Task Async()
        {
            asyncLocal.Value = new WebContext
            {
                Id = 0,
                Name = "父"
            };
            Console.WriteLine("父:" + asyncLocal.Value);
            await Async1();
            Console.WriteLine("父:" + asyncLocal.Value);

        }

        //子上下文
        public static async Task Async1()
        {
            Console.WriteLine("子子:" + asyncLocal.Value);
            asyncLocal.Value = new WebContext
            {
                Name = "子",
                Id = 1,
            };
            Console.WriteLine("子子:修改后");
            Console.WriteLine("子子:" + asyncLocal.Value);
        }

 
    }

    class WebContext
    {
        public string Name { get; set; }
        public int Id { get; set; }

        public override string ToString()
        {
            return $"Name={Name},Id={Id}";
        }
    }

image

AsyncLocal的使用场景

  • 传递状态数据:在异步操作中,例如异步方法或任务链中,我们可能需要共享某些状态数据。使用AsyncLocal,我们可以在异步操作之间传递这些状态数据,而不必显式地传递参数。
  • 上下文相关信息:有时候,我们可能需要跨异步方法或任务访问一些上下文相关的信息,例如用户身份验证信息、语言设置等。使用AsyncLocal,我们可以在整个异步调用栈中访问这些信息,而不必在每个方法中传递它们作为参数。
    //同一个web请求获取 商户上下文数据都是一样的,而且不会影响另外一个web请求
    public class CurrentContext
    {
        /// <summary>
        /// 商户
        /// </summary>
        private static readonly AsyncLocal<CurrentUser> CurrentUser = new AsyncLocal<CurrentUser>();

        public static void SetCurrentData(CurrentUser currentUser)
        {
            CurrentUser.Value = currentUser;
        }

        public static CurrentUser GetCurrentData()
        {
            return CurrentUser.Value??new CurrentUser();
        }
    }

标签:Console,Name,ctx,介绍,AsyncLocal,public,Net,Id
From: https://www.cnblogs.com/lgxlsm/p/17615799.html

相关文章

  • 订单支付_微信支付介绍_微信支付相关接口介绍
        ......
  • Net6.0 集成 Nacos
    1-创建一个WebApi2-添加引用Install-Packagenacos-sdk-csharp-Version1.3.5Install-Packagenacos-sdk-csharp.AspNetCore-Version1.3.5Install-Packagenacos-sdk-csharp.Extensions.Configuration-Version1.3.53-设置appsettings.json{"Nacos":{......
  • Net6.0 集成 支持 Nacos 的 Ocelot 网关
    1-创建Ocelot网关webapi 2-添加引用https://www.cnblogs.com/wucy/p/13353824.htmlInstall-Packagenacos-sdk-csharp-Version1.3.5Install-PackageOcelot.Provider.Nacos-Version1.3.5Install-PackageOcelot.Provider.Polly-Version1.3.53-配置appset......
  • Python小项目:利用 U-net 完成细胞图像分割
    文章目录1前言2实验概述3U-net概述4实验过程及代码5结语完整数据集下载:下载链接1前言在当今数字化时代,图像处理和分析已经成为了科学研究和技术应用领域的关键部分。在生物医学领域,图像分析对于诊断、治疗和疾病研究具有重要意义。本项目将带您深入了解U-net细胞分割技......
  • 计算机视觉智能中医(七):基于Unet模型的舌面裂纹自动分析
    此方法的具体细节与舌体分割类似,只是所用到的数据集不同!代码参照:计算机视觉智能中医(三):基于Unet模型的舌头舌体图片分割舌裂,即舌面裂纹。在中医诊断中健康人群的舌面看起来比较光滑,而舌体上出现各式各样的裂纹往往预示着患有一些疾病。舌裂的提取非常困难,舌面上的裂纹色值与普通舌面......
  • Kubernetes部署v1.26.0
    一,准备环境主机名ip地址节点类型系统版本k8s01192.168.0.180master、etcdcentos7k8s02192.168.0.41workercentos7k8s03192.168.0.241workercentos7  二,配置环境1.修改主机[root@ecs-kmaster~]#hostnamectlset-hostnamekmaster[root@ecs-kma......
  • 使用 OpenTelemetry 构建可观测性 01 - 介绍
    毫无疑问,在过去几年里,你可能已经多次听到过可观测性这个词。对于很多人来说,很难理解这个词的真正含义。对许多人来说,他们错误地将其等同于"监控"。虽然可观测性的根本定义以及它所包含的一切都不在本系列博文的讨论范围之内,但我强烈建议您购买一本由CharityMajors(twitter)、Li......
  • Asp.net WebAPI中Controller的方法在接受到json时序列化都为null的问题
    原因是,webapi默认不序列化字段,只序列化属性只需要把字段改成属性即可 ------------------改成---------------- ......
  • libreadline-dev介绍和例子
    [email protected],2023Descriptionlibreadline-dev介绍和例子简介在实现一个类shell的程序的时候,可能需要使用到命令补全以及命令历史记录。这时候就可以使用libreadline库,这是一个GNU开发的库,官网是:TheGNUReadlineLibrary。这个......
  • Kubernetes实战基础(五)
    本章节将介绍如何在kubernetes集群中部署一个nginx服务,并且能够对其进行访问。5.1NamespaceNamespace是k8s系统中的一种非常重要资源,它的主要作用是用来实现多套环境的资源隔离或者多租户的资源隔离。默认情况下,k8s集群中的所有的Pod都是可以相互访问的。但是在实际中,可能不......