###前提・実現したいこと
Asset
というクラスでアセットファイルの読み込みを行っています。
アセットファイルはアプリ起動後ずっと利用するので、
一度読み込んだ後はメモリ上に残しておきたいと思っています。
調べると、GoFデザインパターのうちSingleton
というのが使えるということが分かり、
以下のように実装しました
C#
1public class Asset 2{ 3 private static Asset _instance; 4 public static Asset Instance 5 { 6 get 7 { 8 if (_instance == null) 9 { 10 _instance = new Asset(); 11 } 12 return _instance; 13 } 14 } 15 16 private Asset() 17 { 18 // コンストラクタでアセットファイルの読み込みを行う 19 } 20}
しかし、アプリ起動後は以下のコードのように複数スレッドを同時に生成するような動きをするため、
Singleton
であっても同時に複数回Asset
クラスが初期化されてしまいました。
その結果、メモリが一気に大量に消費されるような動きとなってしまっています。
C#
1static void Main(string[] args) 2{ 3 Task.Run(() => 4 { 5 Enumerable.Range(0, 10) 6 .ToList() 7 .ForEach(x => AsyncMain()); 8 }); 9}
調べていくとawait
を利用した関数の中で初めて初期化するとこのような動きになることが分かりました。
C#
1static async void AsyncMain() 2{ 3 // 複数回初期化されない 4 var x = Asset.Instance; 5 6 // await の中だと複数回初期化される 7 // var y = await Something.Do(Asset.Instance); 8}
MSDNによると静的コンストラクタは最高で一度だけ実行される
と書かれていました。
The static constructor for a class executes at most once in a given application domain.
https://msdn.microsoft.com/en-us/library/aa645612.aspx
質問
なぜawait
の中で初めてインスタンスの初期化を行うとSingleton
の本来の動きにならない(複数回初期化されてしまう)のでしょうか?
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/10/25 05:05 編集
2016/10/25 07:00
2016/10/25 07:05 編集
2016/10/25 07:18
2016/10/25 07:37