如果我们只让类的内部机制为我们工作,那么线程安全、异步单例的解决方案实际上非常简单Task
!
那么,如何Task
工作?假设您有一个a 的实例,Task<T>
而您await
只使用了一次。现在任务被执行,T
产生一个值并返回给你。如果您再次await
使用相同的任务实例怎么办?在这种情况下,任务只是以完全同步的方式立即返回先前生成的值。
如果您同时从多个线程(通常会出现竞争条件)await
执行相同的任务实例怎么办?好吧,第一个(因为会有一个首先到达那里)将执行任务代码,而其他人将等待处理结果。然后当结果产生时,所有的' 将同时完成(实际上)并返回值。await
所以async
线程安全的单例的解决方案实际上非常简单:
public class Singleton
{
private static readonly Task<Singleton> _getInstanceTask = CreateSingleton();
public static Task<Singleton> Instance
{
get { return _getInstanceTask; }
}
private Singleton(SomeData someData)
{
SomeData = someData;
}
public SomeData SomeData { get; private set; }
private static async Task<Singleton> CreateSingleton()
{
SomeData someData = await LoadData();
return new Singleton(someData);
}
}
现在您可以通过这种方式访问单例:
Singleton mySingleton = await Singleton.Instance;
或者
Singleton mySingleton = Singleton.Instance.Result;
或者
SomeData mySingletonData = (await Singleton.Instance).SomeData;
或者
SomeData mySingletonData = Singleton.Instance.Result.SomeData;
在这里阅读更多:异步单例初始化