AsyncLocal的妙用

打印 上一主题 下一主题

主题 866|帖子 866|积分 2608

AsyncLocal是一个在.NET中用来在同步使命和异步使命中保持全局变量的工具类。
它允许你在差别线程的同一个对象中保留一个特定值,这样你可以在差别的函数和使命中访问这个值。
这是在实现异步使命中维持划一性和优雅性的一种重要本领。
用法

创建一个AsyncLocal实例:
你可以使用AsyncLocal来创建一个特定范例的实例,好比:
  1. AsyncLocal<string> asyncLocalString = new AsyncLocal<string>();
复制代码
设置值:
你可以通过Value属性设置或者读取值:
  1. asyncLocalString.Value = "Hello, AsyncLocal!";
复制代码
读取值:
在使命中的任意位置,你都可以读取这个值:
  1. Console.WriteLine(asyncLocalString.Value);
复制代码
实例分享与给值变更:
在差别使命和串行使命中,AsyncLocal 实例的值是不一样的:
  1. asyncLocalString.Value = "Main Task";
  2. Task.Run(() =>
  3. {
  4.     asyncLocalString.Value = "Child Task";
  5.     Console.WriteLine(asyncLocalString.Value); // 输出 "Child Task"
  6. });
  7. Console.WriteLine(asyncLocalString.Value); // 输出 "Main Task"
复制代码
场景

数据通报:
异步使命中,通过AsyncLocal进行全局数据通报而无需通过参数通报。这对于学习和复用代码很有帮助。
上下文管理:
在ASP.NET Core中,AsyncLocal 可用于管理用户请求上下文,实现差别请求之间的通报。当你需要保存一些请求相关的信息时,这是一种很有用的方法。
百分比信息保存:
记录差别使命和串行使命中的特定信息,说明这些使命是如何分布的。这在分析和跟踪异步操作时应对特别有用。
系统日志和跟踪:
AsyncLocal 可用于在异步使命中保存和分享日志和跟踪信息,以便在运行时收罗最有益的信息,有助于问题跟踪和分析。
示例:保存日志和租户信息

以下是一个使用AsyncLocal保存日志和租户信息的示例:
  1. using System;
  2. using System.Threading;
  3. using System.Threading.Tasks;
  4. public class LogContext
  5. {
  6.     public string StackTrace { get; set; }
  7.     public string UserInfo { get; set; }
  8. }
  9. public class TenantContext
  10. {
  11.     public string Name { get; set; }
  12. }
  13. public class Program
  14. {
  15.     private static AsyncLocal<LogContext> _logContext = new AsyncLocal<LogContext>();
  16.     private static AsyncLocal<TenantContext> _tenantContext = new AsyncLocal<TenantContext>();
  17.     public static async Task Main(string[] args)
  18.     {
  19.         _logContext.Value = new LogContext { StackTrace = "Main Stack Trace", UserInfo = "User1" };
  20.         _tenantContext.Value = new TenantContext { Name = "Tenant A" };
  21.         Console.WriteLine($"Initial Log Context: {_logContext.Value.StackTrace}, User: {_logContext.Value.UserInfo}, Tenant: {_tenantContext.Value.Name}");
  22.         await Task.Run(() => LogAndProcess(new LogContext { StackTrace = "Child Stack Trace", UserInfo = "User2" }, new TenantContext { Name = "Tenant B" }));
  23.         Console.WriteLine($"After Task Log Context: {_logContext.Value.StackTrace}, User: {_logContext.Value.UserInfo}, Tenant: {_tenantContext.Value.Name}");
  24.     }
  25.     private static void LogAndProcess(LogContext logContext, TenantContext tenant)
  26.     {
  27.         _logContext.Value = logContext;
  28.         _tenantContext.Value = tenant;
  29.         Console.WriteLine($"In Task Log Context: {_logContext.Value.StackTrace}, User: {_logContext.Value.UserInfo}, Tenant: {_tenantContext.Value.Name}");
  30.         // Simulate some processing
  31.         Task.Delay(1000).Wait();
  32.         Console.WriteLine($"After Processing Log Context: {_logContext.Value.StackTrace}, User: {_logContext.Value.UserInfo}, Tenant: {_tenantContext.Value.Name}");
  33.     }
  34. }
复制代码
在这个示例中,AsyncLocal 用于保存日志和租户信息,确保在差别的使命上下文中正确通报和使用这些信息。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

泉缘泉

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表