当前位置: 首页 > article >正文

.net core 中使用AsyncLocal传递变量

官网

https://github.com/dotnet/runtime/blob/16b6369b7509e58c35431f05681a9f9e5d10afaa/src/libraries/System.Private.CoreLib/src/System/Threading/AsyncLocal.cs#L45

AsyncLocal是一个在.NET中用来在同步任务和异步任务中保持全局变量的工具类。它允许你在不同线程的同一个对象中保留一个特定值,这样你可以在不同的函数和任务中访问这个值。这是在实现异步任务中维持一致性和优雅性的一种重要手段。

中间件中使用

 public class BaseClass
 {
     public string Id { get; set; }
 }

    public static class AmbientContext
    {
        public static readonly ConcurrentDictionary<string, AsyncLocal<object?>>
            _contexts = new(StringComparer.Ordinal);

        public static void Set<T>(string key, [MaybeNull] T val)
        {
            AsyncLocal<object?> keyctx = _contexts.AddOrUpdate(
                    key,
                    k => new AsyncLocal<object?>(),
                    (k, al) => al);
            keyctx.Value = (object?)val;
        }

        [return: MaybeNull]
        public static T Get<T>(string key)
        {
            return _contexts.TryGetValue(key, out AsyncLocal<object?>? keyctx)
                     ? (T)(keyctx!.Value ?? default(T)!)
                     : default(T);
        }
    }


    public class AmbientContextMiddleware
    {
        private readonly RequestDelegate _next;

        public AmbientContextMiddleware(RequestDelegate next) =>
            _next = next;

        public async Task Invoke(HttpContext context)
        {
            string corrId =
                context.Request
                       .Headers["x-foocorp-correlationId"]
                       .FirstOrDefault(Guid.NewGuid().ToString());

            context.Request.Headers.Add("x-foocorp-correlationId", corrId);

            AmbientContext.Set<BaseClass>(corrId, new BaseClass() { Id=DateTime.Now.ToString()});

            await _next.Invoke(context);

            

            // TODO: emit corrid response header, esp if _we_ created it
        }
    }

[HttpGet]
public async Task<DatasetSmallMovie> GetByID(string id,string indexName)
{
    Console.WriteLine(DateTime.Now.ToString());
    Request.Headers.TryGetValue("x-foocorp-correlationId", out var headersvalue);

    Console.WriteLine(headersvalue);
    await Task.Delay(2000);

    Console.WriteLine(AmbientContext.Get<BaseClass>(headersvalue).Id);

    return await _meilisearchHelper.GetByID<DatasetSmallMovie>(id, indexName);
}


普通使用

    using System;
    using System.Threading;
    using System.Threading.Tasks;
    public class LogContext { public string StackTrace { get; set; } public string UserInfo { get; set; } }
    public class TenantContext { public string Name { get; set; } }
    public class Program
    {
        private static AsyncLocal<LogContext> _logContext = new AsyncLocal<LogContext>(); private static AsyncLocal<TenantContext> _tenantContext = new AsyncLocal<TenantContext>();
        public static async Task Main(string[] args)
        {
            _logContext.Value = new LogContext { StackTrace = "Main Stack Trace", UserInfo = "User1" }; _tenantContext.Value = new TenantContext { Name = "Tenant A" };
            Console.WriteLine($"Initial Log Context: {_logContext.Value.StackTrace}, User: {_logContext.Value.UserInfo}, Tenant: {_tenantContext.Value.Name}");
            await Task.Run(() => LogAndProcess(new LogContext { StackTrace = "Child Stack Trace", UserInfo = "User2" }, new TenantContext { Name = "Tenant B" }));
            Console.WriteLine($"After Task Log Context: {_logContext.Value.StackTrace}, User: {_logContext.Value.UserInfo}, Tenant: {_tenantContext.Value.Name}");
        }
        private static void LogAndProcess(LogContext logContext, TenantContext tenant)
        {
            _logContext.Value = logContext; _tenantContext.Value = tenant;
            Console.WriteLine($"In Task Log Context: {_logContext.Value.StackTrace}, User: {_logContext.Value.UserInfo}, Tenant: {_tenantContext.Value.Name}");
            // Simulate some processing        Task.Delay(1000).Wait();
            Console.WriteLine($"After Processing Log Context: {_logContext.Value.StackTrace}, User: {_logContext.Value.UserInfo}, Tenant: {_tenantContext.Value.Name}");
        }
    }

http://www.kler.cn/a/507136.html

相关文章:

  • eBay账号安全攻略:巧妙应对风险
  • 浅谈云计算20 | OpenStack管理模块(下)
  • RabbitMQ前置概念
  • FreeType 介绍及 C# 示例
  • SDK调用文心一言如何接入,文心一言API接入教程
  • vue项目引入阿里云svg资源图标
  • 【实践功能记录9】使用pnpm打补丁
  • VD:生成a2l文件
  • Lora理解QLoRA
  • iOS - Objective-C 底层中的内存屏障
  • 服务器下发任务镭速利用变量实现高效的大文件传输效率
  • Python人工智能在气象中的应用,包括:天气预测、气候模拟、降雨量和降水预测、气象数据分析、气象预警系统
  • 【Element】一键重置表单resetFields
  • 【开源分享】nlohmann C++ JSON解析库
  • 学习 Git 的工作原理,而不仅仅是命令
  • 《零基础Go语言算法实战》【题目 2-28】读写不安全问题
  • arm使用ubi系统
  • windows10 安装 Golang 版本控制工具g与使用
  • Gartner预测2025年关键基础设施的CPS安全:确保机器人、无人机、自动驾驶汽车、人工智能等前沿技术应用和新场景安全
  • 【Flink系列】6. Flink中的时间和窗口
  • web前端第八次作业---制作音乐榜单
  • Unity WebGL:本机部署,运行到手机
  • 手摸手系列之 Java 通过 PDF 模板生成 PDF 功能
  • 专业140+总分410+宁波大学829信号与系统考研经验宁大电子信息与通信工程,真题,大纲,参考书。
  • 卷积神经网络的底层是傅里叶变换
  • CSS中的accent-color如何使用