このような方法はありますか?
号
だけに、この目的のために非同期メソッドを使用する任意のオーバーヘッドはありますか?
はい。しかし、それは最も簡単な解決策です。
Then
のようなTask
の拡張メソッドであることに注意してください。スティーブン・トゥーはこれを探検しましたin a blog postと私は最近incorporated it into AsyncExです。 TaskCompletionSource<TBase>
独自に作成することであろうわずかに少ないオーバーヘッドで
public Task<TBase> Run()
{
return MethodThatReturnsDerivedTask().Then(x => (TBase)x);
}
別のアプローチ、それは(私のAsyncExライブラリにTryCompleteFromCompletedTask
を使用して)導出結果で完了しました:Then
を使用して
、あなたのコードは次のようになります。
public Task<TBase> Run()
{
var tcs = new TaskCompletionSource<TBase>();
MethodThatReturnsDerivedTask().ContinueWith(
t => tcs.TryCompleteFromCompletedTask(t),
TaskContinuationOptions.ExecuteSynchronously);
return tcs.Task;
}
または(あなたがAsyncExへの依存性を取るしたくない場合):
public Task<TBase> Run()
{
var tcs = new TaskCompletionSource<TBase>();
MethodThatReturnsDerivedTask().ContinueWith(t =>
{
if (t.IsFaulted)
tcs.TrySetException(t.Exception.InnerExceptions);
else if (t.IsCanceled)
tcs.TrySetCanceled();
else
tcs.TrySetResult(t.Result);
}, TaskContinuationOptions.ExecuteSynchronously);
return tcs.Task;
}
を理由だけで、 '(MethodThatReturnsDerivedTaskを返さない)ContinueWith(タスク=>(TBASE)task.Result、TaskContinuationOptions。 .ExecuteSynchronously) '? –
'Result'を使うと、例外は' AggregateException'にラップされ、元のタスクがキャンセルされた状態で完了した場合には完全なフォールトになります。つまり、これらの状況を正しく処理するコードをいくつか追加すれば、 'TaskCompletionSource'を使わずに' ContinueWith'を使って解決策を作ることができます。 –