[C#] 완료된 작업 만들기

완성 된 Task(아닌 Task<T>) 을 만들고 싶습니다 . 이를 위해 .NET에 내장 된 것이 있습니까?

관련 질문 :
완료된 작업 생성 <T>



답변

닷넷 (V4.6)의 최신 버전 단지를 추가, 내장 Task.CompletedTask :

Task completedTask = Task.CompletedTask;

이 속성은 잠금이없는 싱글 톤으로 구현되므로 거의 항상 동일한 완성 된 작업을 사용하게됩니다.


답변

Task<T>암시 적으로 Task로 변환 가능하므로 Task<T>( T임의의 값으로) 완성 된 것을 사용하십시오. 이와 같은 것을 사용하여 실제 결과가 어딘가에 있다는 사실을 숨길 수 있습니다.

private static Task completedTask = Task.FromResult(false);
public static Task CompletedTask()
{
    return completedTask;
}

결과를 공개하지 않고 작업이 항상 완료되었으므로 단일 작업을 캐시하고 재사용 할 수 있습니다.

.NET 4.0을 사용 중이고없는 경우 FromResult다음을 사용하여 직접 만들 수 있습니다 TaskCompletionSource.

public static Task<T> FromResult<T>(T value)
{
    var tcs = new TaskCompletionSource<T>();
    tcs.SetResult(value);
    return tcs.Task;
}


답변

이를 위해 내가 선호하는 방법은 Task.WhenAll()인수없이 호출 하는 것입니다. MSDN 문서 상태는 “제공된 배열 / 열거 더 작업을 포함하지 않는 경우, 반환 작업은 RanToCompletion 상태로 즉시 전환이 호출자에게 반환의 뜻 전에.”. 그것은 당신이 원하는 것 같습니다.

업데이트 : Microsoft의 Reference Source 에서 소스를 찾았습니다 . Task.WhenAll에 다음이 포함되어 있습니다.

return (tasks.Length == 0) ? // take shortcut if there are no tasks upon which to wait
            Task.CompletedTask :
            new WhenAllPromise(tasks);

따라서 Task.CompletedTask는 실제로 내부이지만 인수없이 WhenAll ()을 호출하면 노출됩니다.


답변

사용 Task.Delay(0)합니다. 내부적으로 complete의 캐시 된 인스턴스를 반환합니다 Task<T>. 이것은 현재 답변이 어쨌든 제안하는 것입니다. 지금은 인스턴스를 직접 캐시 할 필요가 없으며 코드에 불필요한 가비지 값이 없습니다.

Task.Yield()대신 사용할 수 있다고 생각할 수도 있지만의 결과 Task.Yield()는 의 하위 유형 이 아니며Task 결과는 Task.Delay(0)입니다. 그것은 둘 사이의 미묘한 차이점 중 하나입니다.


답변

Task.FromResult (.NET 4.5)를 사용하여 완료된을 반환 할 수 있습니다 Task<T>.

제네릭이 아닌을 필요로하는 경우 의 하위 클래스 이므로 Task항상 사용 Task.FromResult(0)하거나 유사 할 수 있습니다 .Task<T>Task


답변

.Net 4.6 이상의 경우

return Task.CompletedTask;

낮은 버전의 경우 사용할 수 있습니다

return new Task(() => { });


답변

Stephen Cleary 의 훌륭한 라이브러리 AsyncEx 에서 Nito.AsyncEx.TaskConstants.Completed 를 사용할 수 있습니다 .