C# AsyncLocal和ThreadLocal的区别

博客讨论了.NET中AsyncLocal和ThreadLocal的使用场景和区别。AsyncLocal在遇到异步方法时会在子任务中重置值,适合异步方法内的对象共享;而ThreadLocal则确保线程内的对象唯一,适用于真正的线程局部存储。示例代码展示了两种情况下的运行结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在日常开发中,往往需要用到 “线程内对象唯一(对象线程内单例)” 的功能,尤其是Web开发中。这时候我们在最新的.NET中会使用AsyncLocal和ThreadLocal这两个对象,下面我们就来探讨下这两个对象的区别。

AsyncLocal遇到Async方法时会重置该Async方法对应的子线程里的Value为null,仅仅只是基于Async方法,并不是真正基于线程的。

要想真正基于线程来操作对象(线程内对象唯一),则应该使用ThreadLocal

首先,我们先看不带async的方法:

/// <summary>
    /// Guid工厂
    /// </summary>
    static class GuidFactory
    {
        //private static ThreadLocal<string> _localGuid = new ThreadLocal<string>();
        private static AsyncLocal<string> _localGuid = new AsyncLocal<string>();
        public static string CurrentGuid
        {
            get
            {
                if (_localGuid.Value == null)
                {
                    _localGuid.Value = Guid.NewGuid().ToString();
                }
                return _localGuid.Value;
            }
        }
    }

    class APP
    {
        private Task<int> awaitFunction()
        {
            Task<int> task = new Task<int>(() =>
            {
                Thread.Sleep(500);
                Console.WriteLine("awaitFunction:" + GuidFactory.CurrentGuid+" id:" + Thread.CurrentThread.ManagedThreadId.ToString());
                return 2;
            });
            task.Start();

            return task;
        }

        private void asyncFunction()
        {
            Console.WriteLine("asyncFunction:" + GuidFactory.CurrentGuid+" id:"+ Thread.CurrentThread.ManagedThreadId.ToString());
            awaitFunction();
            Console.WriteLine("asyncFunction:" + GuidFactory.CurrentGuid + " id:" + Thread.CurrentThread.ManagedThreadId.ToString());
        }


        public APP()
        {
            asyncFunction();
            Console.WriteLine("asyncFunction:" + GuidFactory.CurrentGuid + " id:" + Thread.CurrentThread.ManagedThreadId.ToString());
            while (true)
            {
                Thread.Sleep(1000);
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            APP App = new APP();
            Console.ReadLine();
        }
    }

运行结果如下:

然后我们再看带async的方法:

    /// <summary>
    /// Guid工厂
    /// </summary>
    static class GuidFactory
    {
        //private static ThreadLocal<string> _localGuid = new ThreadLocal<string>();
        private static AsyncLocal<string> _localGuid = new AsyncLocal<string>();
        public static string CurrentGuid
        {
            get
            {
                if (_localGuid.Value == null)
                {
                    _localGuid.Value = Guid.NewGuid().ToString();
                }
                return _localGuid.Value;
            }
        }
    }

    class APP
    {
        private Task<int> awaitFunction()
        {
            Task<int> task = new Task<int>(() =>
            {
                Thread.Sleep(500);
                Console.WriteLine("awaitFunction:" + GuidFactory.CurrentGuid+" id:" + Thread.CurrentThread.ManagedThreadId.ToString());
                return 2;
            });
            task.Start();

            return task;
        }

        private async void asyncFunction()
        {
            Console.WriteLine("asyncFunction:" + GuidFactory.CurrentGuid+" id:"+ Thread.CurrentThread.ManagedThreadId.ToString());
             await awaitFunction();
            Console.WriteLine("asyncFunction:" + GuidFactory.CurrentGuid + " id:" + Thread.CurrentThread.ManagedThreadId.ToString());
        }

        

        public APP()
        {
            asyncFunction();
            Console.WriteLine("asyncFunction:" + GuidFactory.CurrentGuid + " id:" + Thread.CurrentThread.ManagedThreadId.ToString());
            while (true)
            {
                Thread.Sleep(1000);
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            APP App = new APP();
            Console.ReadLine();
        }
    }

运行效果如下:

 综上所述:AsyncLocal只对其async方法内的子线程可以对象共用,或者是多个线程(没有async方法)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值