解决方案为线程安全,异步单例其实超级简单,如果我们只让内部机制Task
给我们上课!
那么,如何Task
工作?假设您有一个instance of a Task<T>
你呢await
一次。现在任务已执行,值为T
被生产并返回给您。如果你怎么办await
the same task instance再次?在这种情况下,任务只是以完全同步的方式立即返回先前生成的值。
如果你await
相同的任务实例同时地来自多个线程(通常会出现竞争条件)?好吧,第一个(因为有will第一个到达那里的人)将执行任务代码,而其他人将等待结果被处理。然后当结果产生后,所有的await
's 将(几乎)同时完成并返回值。
所以解决方案是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;
or
Singleton mySingleton = Singleton.Instance.Result;
or
SomeData mySingletonData = (await Singleton.Instance).SomeData;
or
SomeData mySingletonData = Singleton.Instance.Result.SomeData;
在这里阅读更多内容:异步单例初始化 http://www.laserbrain.se/post/2015/11/22/async-singleton-initialization.aspx