質問

読んでいた TaskCompletionSource の性質, 、Stephen Toub による投稿。

public static Task RunAsync(Action action)
{
    var tcs = new TaskCompletionSource<Object>();
    ThreadPool.QueueUserWorkItem(_ =>
    {
        try
        {
            action();
            tcs.SetResult(null);
        }
        catch(Exception exc) { tcs.SetException(exc); }
    });
    return tcs.Task;
}

もう種類は気にしないので、 T つまり、私はデフォルトで使用しています Object. 。そして、 Action 正常に実行され、 SetResult を移行するために今でも使用されています TaskRanToCompletion 最終状態。ただし、実際の結果の値は無関係であるため、 null 使用されている。 ついに、 RunAsync 戻り値 Task それよりも Task<Object>. 。もちろん、インスタンス化された taskのタイプはまだです Task<Object>, しかし、それ自体を参照する必要はなく、このメソッドの利用者はそれらの実装の詳細を気にする必要はありません。

なぜメソッドが返されるのか特にわかりません Task それよりも Task<object> (太字の文を強調したのはそのためです)。メソッドが return に設定されていることは知っています Task しかし tcs です TaskCompletionSource<Object>, 、 ない TaskCompletionSource (それは間違っていると思います)。

役に立ちましたか?

解決

一般的なTaskCompletionSourceは存在しないため、必要なすべてのタスクはその結果、結果は問題ではありません。 呼び出し側は、タスクが実際にはTask<object>であることを知らせていません。発信者は実際の結果に気付いていません。

もちろん、awaitTask<T>

から継承するという事実によって促進されます。


Falseを返すTaskを見つけるのも一般的です。

他のヒント

TaskCompletionSourceのインスタンスではないTaskのインスタンスを作成するための非一般的なTask<T>クラスはありません。これにより、戻り値を気にしない(または提供されていない)ときに、TaskCompletionSource<T>のGeneric Typeパラメータに2つのオプションが残っています。

  1. Return型として、objectなどの任意の既存のタイプを使用します。タスクの完了を示すには、値をnullに設定します。
  2. 特定の非公開タイプを使用し、タスクの完了を示すために値をnullに設定します。
  3. 戻り値がないTaskCompletionSource<T>を提供する目的でTaskインスタンスを作成するときは、専用の非公開タイプを使用して、その結果、結果が発生したTaskのインスタンスとして返されたTask<T>を間違えないようにします。意味。

    まず、次のクラスを定義します(別の型の内側にネストされている場合はprivate sealed classにすることができます):

    internal sealed class VoidResult
    {
    }
    
    .

    その後、完了元のTaskCompletionSource<object>を使用する代わりに、TaskCompletionSource<VoidResult>を使用します。 VoidResultタイプはコードを呼び出してアクセスできないため、ユーザーはTaskオブジェクトをTask<VoidResult>のインスタンスにキャストできません。

なぜメソッドが返されるのか特にわかりません Task それよりも Task<object>

だって帰ってきたら Task<Object> これは、このメソッドが完了すると、次の型の有用な値が生成されることを意味します。 Object. 。この場合、結果は何も生成されません。だからこそ、スティーブンは戻ることを選択します。 Task.

私たちが扱っているのであれば Func<Object> それから戻る Task<Object> として適切でしょう Func 何らかの結果が生成される場合は、それを返すことを選択する場合があります。

なぜ TaskCompletionSource<Object>, 、 ない TaskCompletionSource?

そんなことないから。非ジェネリックはありません TaskCompletionSource.

Task<object>を返した場合、var result = await RunAsync(...)は常に結果を設定しているものです。

クライアントはこれを気にしませんので、nullを返します。

理想的には、Taskの代わりにTaskCompletionSourceを内部的に使用し、TaskCompletionSource<object>の代わりにSetCompleted()のようなものと呼びます。しかし、そのような種類は存在しません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top