经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » ASP.net » 查看文章
.Net AsyncLocal介绍
来源:cnblogs  作者:广州大雄  时间:2023/8/16 9:14:19  对本文有异议

AsyncLocal的基本概念

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

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

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

image

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

  • 每个节点都可以有自己的对象;
  • 当子节点没有设置对象时,则访问的是父节点的对象;
  • 当子节点设置了对象时,则访问自己设置的对象;
  • 父节点无法访问子节点设置的对象;
  1. class Program
  2. {
  3. private static AsyncLocal<WebContext> asyncLocal = new AsyncLocal<WebContext>();
  4. static async Task Main(string[] args)
  5. {
  6. await Async();
  7. Console.Read();
  8. }
  9. //父上下文
  10. public static async Task Async()
  11. {
  12. asyncLocal.Value = new WebContext
  13. {
  14. Id = 0,
  15. Name = "父"
  16. };
  17. Console.WriteLine("父:" + asyncLocal.Value);
  18. await Async1();
  19. Console.WriteLine("父:" + asyncLocal.Value);
  20. }
  21. //子上下文
  22. public static async Task Async1()
  23. {
  24. Console.WriteLine("子子:" + asyncLocal.Value);
  25. asyncLocal.Value = new WebContext
  26. {
  27. Name = "子",
  28. Id = 1,
  29. };
  30. Console.WriteLine("子子:修改后");
  31. Console.WriteLine("子子:" + asyncLocal.Value);
  32. }
  33. }
  34. class WebContext
  35. {
  36. public string Name { get; set; }
  37. public int Id { get; set; }
  38. public override string ToString()
  39. {
  40. return $"Name={Name},Id={Id}";
  41. }
  42. }

image

AsyncLocal的使用场景

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

原文链接:https://www.cnblogs.com/lgxlsm/p/17615799.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号