よくある初期化用lock
private static object thisLock = new object();
private static SomeObj some;
public void Hoge()
{
// まだ作られてなければ作る
if (some == null)
{
lock (thisLock)
{
if (some == null)
{
some = CreateSome();
}
}
}
// 以降の処理
}
気になる
- ネスト深い
- objectの用途を名前で表明するしかない
ラップするクラスを作ってみる
public class ObjectForLock
{
/// <summary>
/// 指定したconditionがtrueを返す時自分自身のlockを取得し再度conditionがtrueを返した時指定したactionを実行します
/// </summary>
/// <param name="condition"></param>
/// <param name="action"></param>
public void IsolateAction(Func<bool> condition, Action action)
{
if (condition() == false) return;
lock (this)
{
if (condition() == false) return;
action.Invoke();
}
}
}
先ほどの例を置き換えてみる
private static ObjectForLock thisLock = new ObjectForLock();
private static SomeObj some;
public void Hoge()
{
// まだ作られてなければ作る
thisLock.IsolateAction(
() => some == null,
() => { some = CreateSome(); });
// 以降の処理
}
- ネスト無い
- lock用のオブジェクトであることが型を見ればわかる
地味に便利