基本的に他のメソッドをラップする便利なメソッドを持つコードを書くことがよくあります。簡単な例を次に示します。
public class WithoutAsync
{
public static ReadOnlyCollection<Response> GetResponses(IEnumerable<Request> fromRequests)
{
var ret = new List<Response>();
foreach (Request r in fromRequests)
{
ret.Add(new Response());
}
return ret.AsReadOnly();
}
//convenience method
public static Response GetResponse(Request fromRequest)
{
return GetResponses(new Request[] {fromRequest})[0];
}
}
今、私はawait
長時間実行する操作をしたいのですが、この方法論を TPL で使用するために改造する方法がよくわかりません。
public class WithAsync
{
public static async Task<ReadOnlyCollection<Response>> GetResponses(IEnumerable<Request> fromRequests)
{
var awaitableResponses = new List<Task<Response>>();
foreach (Request r in fromRequests)
{
awaitableResponses.Add(Task.Run<Response>(async () =>
{
await Task.Delay(10000); //simulate some long running async op.
return new Response();
}));
}
return new List<Response>(await Task.WhenAll(awaitableResponses)).AsReadOnly();
}
//convenience method
public static Task<Response> GetResponse(Request fromRequest)
{
return GetResponse(new Request[] { fromRequest });
}
}
Task<ReadOnlyCollection<Response>>
上記の便利なメソッドは、本当に a を返す必要があるときに a を返そうとしているため、明らかに機能しませんTask<Response>
。
これは機能します:
//convenience method
public static Task<Response> GetResponse(Request fromRequest)
{
return new Task<Response>(new Func<Response>(() => GetResponse(new Request[] { fromRequest }).Result[0]));
}
しかし、それは本当にぎこちなく見えます。さらに重要なこと.Result[0]
に、UI スレッド上にある可能性のあるものをブロックします。
私がやろうとしていることを達成する良い方法はありますか?