浅析C#中的AsnycLocal与ThreadLocal

 更新时间:2021年09月30日 14:16:07   作者:沉默的雪糕  
这篇文章主要给大家介绍了关于C#中AsnycLocal与ThreadLocal的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

AsnyncLocal与ThreadLocal都是存储线程上下文的变量,但是,在实际使用过程中两者又有区别主要的表现在:

  • AsyncLocal变量可以在父子线程中传递,创建子线程时父线程会将自己的AsyncLocal类型的上下文变量赋值到子线程中,但是,当子线程改变线程上下文中AsnycLocal变量值后,父线程不会同步改变。也就是说AsnycLocal变量只会影响他的子线程,不会影响他的父级线程。
  • TreadLocal只是当前线程的上下文变量,不能在父子线程间同步。
using System;
using System.Threading;
using System.Threading.Tasks;

namespace await_aysnc
{
    class Program
    {
        static ThreadLocal<int> ThreadObj = new ThreadLocal<int>();
        static AsyncLocal<int> AsyncObj = new AsyncLocal<int>();

        static void Main(string[] args)
        {
            AsyncObj.Value = 1;
            ThreadObj.Value = 1;
            Console.WriteLine($"Task执行前:AsyncObj= {AsyncObj.Value} ThreadObj= {ThreadObj.Value} ThreeadId = {Thread.CurrentThread.ManagedThreadId}");
            Task.Run(async() =>
            {
                Console.WriteLine($"RunAsync异步执行前:AsyncObj= {AsyncObj.Value} ThreadObj= {ThreadObj.Value} ThreeadId = {Thread.CurrentThread.ManagedThreadId}");
                await RunAsync();
                Console.WriteLine($"RunAsync异步执行后:AsyncObj = {AsyncObj.Value} ThreadObj= {ThreadObj.Value} ThreeadId = {Thread.CurrentThread.ManagedThreadId}");
            });
            Console.WriteLine($"Task执行后:AsyncObj= {AsyncObj.Value} ThreadObj= {ThreadObj.Value} ThreeadId = {Thread.CurrentThread.ManagedThreadId}");
            Console.Read();
        }

        static async Task RunAsync()
        {           
            Console.WriteLine($"Delay异步执行前:AsyncObj = {AsyncObj.Value} ThreadObj= {ThreadObj.Value} ThreeadId = {Thread.CurrentThread.ManagedThreadId} ");
            AsyncObj.Value = 2;
            ThreadObj.Value = 2;
            await Task.Delay(100);
            Console.WriteLine($"Delay异步执行后:AsyncObj = {AsyncObj.Value} ThreadObj= {ThreadObj.Value} ThreeadId = {Thread.CurrentThread.ManagedThreadId}");
        }
    }

}

Task执行前:AsyncObj= 1 ThreadObj= 1 ThreeadId = 1
Task执行后:AsyncObj= 1 ThreadObj= 1 ThreeadId = 1
RunAsync异步执行前:AsyncObj= 1 ThreadObj= 0 ThreeadId = 3
Delay异步执行前:AsyncObj = 1 ThreadObj= 0 ThreeadId = 3
Delay异步执行后:AsyncObj = 2 ThreadObj= 0 ThreeadId = 4
RunAsync异步执行后:AsyncObj = 1 ThreadObj= 0 ThreeadId = 4

从结果上可以看出一下结论:

  • RunAsync执行前ThreadLocal值被切成0即ThreadLocal变量在新线程里面没有继承主线程的上下文变量,但是AsyncLocal继承了。
  • Delay返回后,线程id变了,同时,TheadLocal中的变量为0。
  • RunAsync结束后AyncLocal又切回主线程的上下文值,,同样Threadlocal中的值丢失。
  • 由于await执行完返回之后,.net会在线程池中随机选取一个线程来执行await之后的逻辑,所以,await之后同时也会有一定几率获取到之前的线程,如果出现这种情形,TreadLocal会获取到之前的上下文,此时会出现意料之外的问题,从现象上看报错可能会是一个概率性问题。

总结

到此这篇关于C#中AsnycLocal与ThreadLocal的文章就介绍到这了,更多相关C#的AsnycLocal与ThreadLocal内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • ToLua框架下C#与Lua代码的互调操作

    ToLua框架下C#与Lua代码的互调操作

    这篇文章主要介绍了ToLua框架下C#与Lua代码的互调操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-11-11
  • c# 组合模式

    c# 组合模式

    组合模式:将对象组合成树形结构以表示‘部分-整体’的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。需求中式体现部分与整体层次的结构时,统一地使用组合对象中的所有对象时,应该考虑使用组合模式
    2012-10-10
  • 简单了解C#设计模式编程中的桥接模式

    简单了解C#设计模式编程中的桥接模式

    这篇文章主要介绍了C#设计模式编程中的桥接模式,桥接模式经常应用于解耦逻辑层与数据操作层,需要的朋友可以参考下
    2016-02-02
  • C#获取目录最后访问时间的方法

    C#获取目录最后访问时间的方法

    这篇文章主要介绍了C#获取目录最后访问时间的方法,涉及C#中LastAccessTime方法的使用技巧,需要的朋友可以参考下
    2015-04-04
  • 简单实现winform编辑器

    简单实现winform编辑器

    这篇文章主要教大家如何简单实现winform编辑器,功能很简单,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-08-08
  • C#如何优雅的对WinForm窗体应用程序进行权限控制

    C#如何优雅的对WinForm窗体应用程序进行权限控制

    经常会出现winfrom页面需要加载权限树,下面这篇文章主要给大家介绍了关于C#如何优雅的对WinForm窗体应用程序进行权限控制的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-11-11
  • C#不重复输出一个数组中所有元素的方法

    C#不重复输出一个数组中所有元素的方法

    这篇文章主要介绍了C#不重复输出一个数组中所有元素的方法,涉及C#针对数组的遍历、校验及排序等操作技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-08-08
  • C#获取项目指定目录下文件的方法

    C#获取项目指定目录下文件的方法

    这篇文章主要介绍了C#获取项目指定目录下文件的方法,涉及C#操作目录及文件的技巧,非常具有实用价值,需要的朋友可以参考下
    2015-04-04
  • 基于WPF实现边缘停靠效果

    基于WPF实现边缘停靠效果

    这篇文章主要为大家信息介绍了如何基于WPF实现边缘停靠效果,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-01-01
  • C#使用Socket发送和接收TCP数据实例

    C#使用Socket发送和接收TCP数据实例

    这篇文章主要介绍了C#使用Socket发送和接收TCP数据的实现方法,以实例的形式详细讲述了C#实现socket通信的完整实现过程,非常具有实用价值,需要的朋友可以参考下
    2014-10-10

最新评论