C# AsyncLocal和ThreadLocal的区别

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

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

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

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

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

    class APP
    {
        private Task awaitFunction()
        {
            Task task = new Task(() =>
            {
                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();
        }
    }

运行结果如下:

C# AsyncLocal和ThreadLocal的区别_第1张图片

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

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

    class APP
    {
        private Task awaitFunction()
        {
            Task task = new Task(() =>
            {
                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();
        }
    }

运行效果如下:

C# AsyncLocal和ThreadLocal的区别_第2张图片

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

你可能感兴趣的:(C#,.NET,ASP.NET,c#,asp.net,后端)