クラスの内部メカニズムのみを機能させる場合、スレッドセーフな非同期シングルトンのソリューションは実際には非常に単純です。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;
詳細はこちら:非同期シングルトン初期化