以前にid:neueccさんが、Build Insider Offlineで披露してたAsyncLazy
publicclass AsyncLazy<T> : Lazy<Task<T>> { public AsyncLazy(Func<T> valueFactory) : base(() => Task.Factory.StartNew(valueFactory)) { } public AsyncLazy(Func<Task<T>> taskFactory) : base(() => Task.Factory.StartNew(() => taskFactory()).Unwrap()) { } public TaskAwaiter<T> GetAwaiter() { return Value.GetAwaiter(); } }
Lazy<T>のTの部分をTask<T>にしてGetAwaiterを定義してやるだけでawaitで値をとってこれるLazyができちゃうなんて柔軟すぎる…。気になるのはid:neueccさんが、ちょっと手を入れて使ってますといったところ。何かこれで不都合がでたのかなぁ。
あとスライドにしれっとAsyncLazy.WhenAll(p.Name, p2.Name, p3.Name)みたいなものが出てたけどAsyncLazyがTaskを包んだだけのLazyだとしたら以下のような実装でAsyncLazyの実装はいけそう?
publicstaticclass AsyncLazy { publicstatic Task WhenAll<T>(params AsyncLazy<T>[] ls) { // Lazy<Task<T>>[]からTask<T>[]に変換してTask.WhenAllするreturn Task.WhenAll(ls.Select(l => l.Value).ToArray()); } }
ふむふむ。