1

Что происходит с TaskCompletionSource и его Task если TaskCompletionSource никогда не завершается (т.е. SetCancelled, SetException или SetResult никогда не называют? Будет ли Task жить вечно, потому что она никогда не закончится?Должен ли я всегда заполнять объект TaskCompletionSource?

В приведенном ниже примере я упрощенный (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); 
} 

Пока мы находимся у него, есть ли способ улучшить описанный выше тест (например, сделать его еще более кратким/простым/удобочитаемым)?

ответ

5

Нужно ли выполнять какую-либо очистку (например, убедитесь, что вызывается tcs.SetCancelled())?

Использование TaskCompletionSource<T> не требует никакой очистки. Фактически, он даже не допускает никакой очистки. Поэтому ответ на ваш вопрос «нет».

TaskCompletionSource<T> просто концептуально простая структура данных, которая позволяет передавать в в большинстве одна вещь (результат типа T, исключения или отмены). Свойство Task предоставляет Task<T>, что является просто оберткой вокруг этой обещанной единственной вещи, которая будет вдавлена ​​в TaskCompletionSource<T> в будущем. Он не использует пул задач вообще.

Нельзя толкать ничего в TaskCompletionSource<T>. Это просто соответствует Task<T>, который будет «работать» навсегда и никогда не будет завершен.

Смежные вопросы