4

が完了しない場合 (つまり、またはが呼び出されない場合)TaskCompletionSourceとその はどうなりますか? 完了しないため、 は永遠に存続しますか?TaskTaskCompletionSourceSetCancelledSetExceptionSetResultTask

以下の例では、パラメーター化されたテストの簡略化されたバージョンがあります。タイムアウト (MyEeventが 1000 ミリ秒以内に呼び出されない) の場合、 TaskCompletionSource( tcs) は完了しません。私はこのような多くのテストを持っています。なんらかのクリーンアップを行う必要がありますか (たとえば、tcs.SetCancelled() が呼び出されていることを確認します)。

[Theory]
[InlineData("aa")]
[InlineData(2)]
[InlineData(true)]
[InlineData(null)]
public async Task RaiseMyEvent_RaisesMyEvent_WithOriginalValue(object value)
{
    var sut = new Thing();
    var tcs = new TaskCompletionSource<object>();
    sut.MyEvent += (_, args) => tcs.SetResult(args.Value);

    sut.RaiseMyEvent(value);

    tcs.Task.Should().BeSameAs(await Task.WhenAny(Task.Delay(1000), tcs.Task), "MyEvent should be raised within 1000ms");
    tcs.Task.Result.Should().Be(value);
}

現在、上記のテストを改善する方法はありますか (たとえば、より簡潔/シンプル/読みやすくするなど)?

4

1 に答える 1

7

何らかのクリーンアップを行う必要がありますか (たとえば、tcs.SetCancelled()が呼び出されていることを確認するなど)?

a を使用しTaskCompletionSource<T>ても、クリーンアップは必要ありません。実際、クリーンアップさえ認めていません。したがって、あなたの質問に対する答えは「いいえ」です。

、多くても 1 つのもの ( type 、例外、またはキャンセルの結果)TaskCompletionSource<T>をプッシュできる概念的に単純なデータ構造です。そのプロパティは、将来のある時点で にプッシュされる、この約束された単一のものの単なるラッパーである を公開します。タスクプールは一切使用しません。TTaskTask<T>TaskCompletionSource<T>

何もプッシュしないことTaskCompletionSource<T>は完全に有効です。Task<T>これは、永久に「実行」され、決して完了することのない に相当します。

于 2014-12-02T16:58:18.967 に答える