88

(待機可能な) タスクを返すものへのコールバックを使用する「クラシック」非同期メソッドを変換/ラップする最良の方法は何でしょうか?

たとえば、次のメソッドがあるとします。

public void GetStringFromUrl(string url, Action<string> onCompleted);

これをタスクを返すメソッドにラップする唯一の方法は次のとおりです。

public Task<string> GetStringFromUrl(string url)
{
     var t = new TaskCompletionSource<string>();

     GetStringFromUrl(url, s => t.TrySetResult(s));

     return t.Task;
}

これがこれを達成する唯一の方法ですか?

また、GetStringFromUrl(url,callback) への呼び出しをタスク自体にラップする方法はありますか (つまり、呼び出し自体は同期ではなくタスク内で実行されます)。

4

2 に答える 2

45

あなたのコードは短く、読みやすく、効率的であるため、なぜ代替案を探しているのかわかりませんが、何も思いつきません。あなたのアプローチは合理的だと思います。

Taskまた、同期部分は元のバージョンでは問題ないのに、ベースのバージョンではそれを避けたいと考えている理由もわかりません。同期部分に時間がかかりすぎると思われる場合は、両方のバージョンのメソッドで修正してください。

ただし、バージョンでThreadPoolのみ非同期に (つまり で) 実行したい場合は、次を使用できます。TaskTask.Run()

public Task<string> GetStringFromUrl(string url)
{
    return Task.Run(() =>
    {
        var t = new TaskCompletionSource<string>();

        GetStringFromUrl(url, s => t.TrySetResult(s));

        return t.Task;
    });
}
于 2012-08-09T12:23:25.850 に答える
6

コールバックが成功した状況のみを処理すると仮定すると、想定される実装はこれに対して完全に問題ありません。GetStringFromUrl 実装の非同期基盤内で例外が発生した場合、現在はどうなりますか? それを Action コールバックに伝達する実際の方法はありません...彼らはそれを飲み込んでnullまたは何かを返しますか?

私がお勧めする唯一のことは、このような非同期メソッドに XXXAsync サフィックスを付けて命名するという新しい規則に従って使用することです。

于 2012-08-09T22:20:48.123 に答える