AsyncLocal<T>是一个在.NET中用来在同步任务和异步任务中保持全局变量的工具类。

它允许你在不同线程的同一个对象中保留一个特定值,这样你可以在不同的函数和任务中访问这个值。

这是在实现异步任务中维持一致性和优雅性的一种重要手段。

用法

创建一个AsyncLocal实例:

你可以使用AsyncLocal<T>来创建一个特定类型的实例,比如:

AsyncLocal<string> asyncLocalString = new AsyncLocal<string>();

设置值:

你可以通过Value属性设置或者读取值:

asyncLocalString.Value = "Hello, AsyncLocal!";

读取值:

在任务中的任意位置,你都可以读取这个值:

Console.WriteLine(asyncLocalString.Value);

实例分享与给值变更:

在不同任务和串行任务中,AsyncLocal 实例的值是不一样的:

asyncLocalString.Value = "Main Task";
Task.Run(() =>
{
asyncLocalString.Value = "Child Task";
Console.WriteLine(asyncLocalString.Value); // 输出 "Child Task"
});
Console.WriteLine(asyncLocalString.Value); // 输出 "Main Task"

值变更时的事件触发:

AsyncLocal 充分利用于在值变化时触发特定事件。你可以通过添加处理函数来监听值的变更:

asyncLocalString.ValueChanged += (sender, e) =>
{
Console.WriteLine($"Old Value: {e.PreviousValue}, New Value: {e.CurrentValue}");
};
asyncLocalString.Value = "New Value";

场景

数据传递:

异步任务中,通过AsyncLocal进行全局数据传递而无需通过参数传递。这对于学习和复用代码很有帮助。

上下文管理:

在ASP.NET Core中,AsyncLocal 可用于管理用户请求上下文,实现不同请求之间的传递。当你需要保存一些请求相关的信息时,这是一种很有效的方法。

百分比信息保存:

记录不同任务和串行任务中的特定信息,说明这些任务是如何分布的。这在分析和跟踪异步操作时应对特别有用。

系统日志和跟踪:

AsyncLocal 可用于在异步任务中保存和分享日志和跟踪信息,以便在运行时采集最有益的信息,有助于问题跟踪和分析。

示例:保存日志和租户信息

以下是一个使用AsyncLocal保存日志和租户信息的示例:

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}");
}
}

在这个示例中,AsyncLocal 用于保存日志和租户信息,确保在不同的任务上下文中正确传递和使用这些信息。

AsyncLocal的妙用的更多相关文章

  1. 【CSS进阶】伪元素的妙用--单标签之美

    最近在研读 <CSS SECRET>(CSS揭秘)这本大作,对 CSS 有了更深层次的理解,折腾了下面这个项目: CSS3奇思妙想 -- Demo (请用 Chrome 浏览器打开,非常值 ...

  2. angular2系列教程(十)两种启动方法、两个路由服务、引用类型和单例模式的妙用

    今天我们要讲的是ng2的路由系统. 例子

  3. JavaScript的妙与乐(一)之 函数优化

    JavaScript的妙与乐系列文章主要是展示一些JavaScript上面比较好玩一点的特性和一些有用的技巧,里面很多内容都是我曾经在项目中使用过的一些内容(当然,未必所有技巧的使用频率都很高^_^) ...

  4. Promise的前世今生和妙用技巧

    浏览器事件模型和回调机制 JavaScript作为单线程运行于浏览器之中,这是每本JavaScript教科书中都会被提到的.同时出于对UI线程操作的安全性考虑,JavaScript和UI线程也处于同一 ...

  5. 【.NET深呼吸】基于异步上下文的本地变量(AsyncLocal)

    在开始吹牛之前,老周说两个故事. 第一个故事是关于最近某些别有用心的人攻击.net的事,其实我们不用管它们,只要咱们知道自己是.net爱好者就行了,咱们就是因为热爱.net才会选择它.这些人在这段时间 ...

  6. 【CSS进阶】伪元素的妙用2 - 多列均匀布局及title属性效果

    最近无论是工作还是自我学习提升都很忙,面对长篇大论的博文总是心有余而力不足,但又不断的接触学习到零碎的但是很有意义的知识点,很想分享给大家,所以本篇可能会很短. 本篇接我另一篇讲述 CSS 伪元素的文 ...

  7. 不太被人提起的%%lockres%%的妙用

    %%lockres%% 这个值似乎很少被大家提到,甚至微软在官方文档中. 它返回是一个Hash Value,看乎这个值没什么用. 后来在实践也有它的妙用之处,比如在出现性能问题如LOCK时,一般先通过 ...

  8. 【优雅代码】深入浅出 妙用Javascript中apply、call、bind

    这篇文章实在是很难下笔,因为网上相关文章不胜枚举. 巧合的是前些天看到阮老师的一篇文章的一句话: “对我来说,博客首先是一种知识管理工具,其次才是传播工具.我的技术文章,主要用来整理我还不懂的知识.我 ...

  9. 【javascript 技巧】Array.prototype.slice的妙用

    Array.prototype.slice的妙用 开门见山,关于Array 的slice的用法可以参考这里 http://www.w3school.com.cn/js/jsref_slice_arra ...

  10. EF6 Power Tools的妙用和问题

    环境:vs2013+EF:6.1.3.0+Power Tools:Beta 4 power tools:是一个反向工程,在已有数据库的情况下,可以利用它生成Code Frist模式的代码. 问题: 它 ...

随机推荐

  1. Redhat7重置root管理员密码

    如果要重置Red Hat Enterprise Linux Server release 7.0 的root常见有2种办法(均测试有效) rd.break方法 1.重启Linux系统主机并出现引导界面 ...

  2. 如何用 Spring AI + Ollama 构建生成式 AI 应用

    为了构建生成式AI应用,需要完成两个部分: AI大模型服务:有两种方式实现,可以使用大厂的API,也可以自己部署,本文将采用ollama来构建 应用构建:调用AI大模型的能力实现业务逻辑,本文将采用S ...

  3. 3.4 Linux文件(目录)命名规则

    介绍完 Linux 系统中目录结构之后,读者一定想知道如何为文件或目录命名. 我们知道,在 Linux 系统中,一切都是文件,既然是文件,就必须要有文件名.同其他系统相比,Linux 操作系统对文件或 ...

  4. pyenv: no such command `virtualenv'

    当执行 pyenv virtualenv 3.6.10 env_3.6.10 命令创建新的python环境时提示 pyenv: no such command `virtualenv' larryma ...

  5. 使用WebRTC技术搭建小型的视频聊天页面

    目录 目录 参考资料 什么是WebRTC? 能做什么? 架构图 个人理解(类比) 核心知识点 核心知识点类比 ICE框架 STUN(协议) NAT(网络地址转换) TURN SDP(会话描述协议) W ...

  6. CritiCS:智能协作下的创意长篇故事生成框架 | EMNLP'24

    来源:晓飞的算法工程笔记 公众号,转载请注明出处 论文: Collective Critics for Creative Story Generation 论文地址:https://arxiv.org ...

  7. ETCD存储满了如何处理?

    一.前言 当运行 ETCD 日志报 Erro: mvcc database space exceeded 时,或者查看健康状态显示 failed to commit proposal: Active ...

  8. Winform Tab增加关闭标签页

    Winform的Tab控件,有新增有移除,但是呢,缺了一个标签页上的关闭按钮,这个东西说重要也重要,说不重要也不重要. 这里就说一下怎么添加这玩意. 这玩意需要重绘tab控件,所以我们需要处理Draw ...

  9. Java并发 —— 线程并发(一)

    线程和进程 进程就是一个内存中运行的应用程序 线程是当前进程中的一个执行任务(控制单元),负责当前进程中程序的执行 区别与联系 根本区别:进程是操作系统资源分配的基本单位,线程是处理器任务调度和执行的 ...

  10. Vue-Router 面试题 (2023-09-13更新)

    路由导航守卫 和 Vue 实例生成周期钩子函数的执行顺序? 路由导航守卫 都是在 Vue 实例生命周期钩子函数 之前执行的 Vue-Router 有哪几种导航钩子? 1. 全局守卫 全局前置守卫:be ...