在日常开发中,往往需要用到 “线程内对象唯一(对象线程内单例)” 的功能,尤其是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方法)