31. 31
Lazy Revisited
• 昔ながらのLazyなスタイル
• プロパティに初回アクセスあった時に生成
• Pros
• 使うのが簡単
• Cons
• それが遅延なのか分からない
• 何気なく呼んだらDBアクセスが!とか
MyClass myProperty;
public MyClass MyProperty
{
get
{
if (myProperty == null)
{
myProperty = new MyClass();
}
return myProperty;
}
}
32. 32
Lazy Revisited
• Lazy<T>なスタイル
• Pros
• Lazyなのが明示的
• Cons
• 使うのが面倒(毎回.Value…)
public Lazy<MyClass> MyProperty { get; private set; }
public Toaru()
{
MyProperty = new Lazy<MyClass>(() => new MyClass());
}
33. 33
AsyncLazy
• AwaitableなLazy
• オリジナルはMSのPfxチームから
• http://blogs.msdn.com/b/pfxteam/archive/2011/01/15/101
16210.aspx
• ちょっとだけカスタマイズして使っています
var person = new Person();
var name = await person.Name; // awaitで初期化・取得できる
// 複数同時初期化が可能
await AsyncLazy.WhenAll(person1.Name, person2.Name, person3.Name);
34. 34
AsyncLazy + Redis/DB
public AsyncLazy<string> Name { get; set; }
public AsyncLazy<int> Age { get; set; }
public Person()
{
Name = new AsyncLazy<string>(() => Redis.GetString("Name" + id));
Age = new AsyncLazy<int>(() =>
{
using(var dbConn = …) {
return dbConn.Query<int>(“select age from . where id = @id”);
}
}
}
// RedisがパイプラインでNameを同時初期化
await AsyncLazy.WhenAll(person1.Name, person2.Name, person3.Name);
// DBがマルチスレッドでAgeを同時初期化
await AsyncLazy.WhenAll(person1.Age, person2.Age, person3.Age);
35. 35
AsyncLazy + Redis/DB
public AsyncLazy<string> Name { get; set; }
public Person()
{
Name = new AsyncLazy<string>(() =>
{
var name = Redis.GetString("Name" + id));
if(name == null)
{
using(var conn = new Connection())
{
name = conn.Query<string>();
}
}
return name;
});
}
// データがあればRedisがパイプラインで、なければDBがマルチスレッドでNameを同時初期化
await AsyncLazy.WhenAll(person1.Name, person2.Name, person3.Name);