완료된 작업 생성 <T>


125

메서드를 구현하고 Task<Result> StartSomeTask()있으며 메서드가 호출되기 전에 이미 결과를 알고 있습니다. 이미 완료된 Task <T> 를 어떻게 만듭니 까?

이것이 내가 현재하고있는 일입니다.

private readonly Result theResult = new Result();

public override Task<Result> StartSomeTask()
{
    var task = new Task<Result>(() => theResult);
    task.RunSynchronously(CurrentThreadTaskScheduler.CurrentThread);
    return task;
}

더 나은 해결책이 있습니까?


6
Task <T>가 Task에서 상속하기 때문에이 질문에 대한 답변은 일반 Task (<T> 아님)를 만드는데도 효과적입니다.
Tim Lovell-Smith

오늘 ValueTask완료된 작업 (예 : 코드가 본질적으로 동기가되도록 이미 보유한 값)이 있으므로 할당이 절약됩니다.
nawfal

답변:


111
private readonly Result theResult = new Result();

public override Task<Result> StartSomeTask()
{
    var taskSource = new TaskCompletionSource<Result>();
    taskSource.SetResult(theResult);
    return taskSource.Task;
}

@DanielLobo 반대 의견에 대해 설명하면 답변을 얻을 수 있습니다.
user2023861

1
아래 표가 더 단순하고 더 많은 표를 얻지 않아야합니까? @ user2023861
Daniel Lobo

203

.NET 4.5를 대상으로 할 때 다음을 사용할 수 있습니다 Task.FromResult.

public static Task<TResult> FromResult<TResult>(TResult result);

실패한 작업을 만들려면 다음을 사용하십시오 Task.FromException.

public static Task FromException(Exception exception);
public static Task<TResult> FromException<TResult>(Exception exception);

Task.CompletedTask일반이 아닌 .NET 4.6이 추가 됩니다 Task.

public static Task CompletedTask { get; }

이전 버전의 .NET에 대한 해결 방법 :

  • 비동기 타겟팅 팩 (또는 AsyncCTP)을 사용하여 .NET 4.0을 대상으로하는 경우 TaskEx.FromResult대신 사용할 수 있습니다 .

  • Task.NET 4.6 이전에 제네릭이 아닌 것을 얻으려면 or Task<T>에서 파생되어 Task호출 한다는 사실을 사용할 수 있습니다 .Task.FromResult<object>(null)Task.FromResult(0)


13
일반 작업이 아닌 작업을 반환하려면 Task.FromResult (0)와 같은 것을 사용하는 것이 좋습니다. "null"을 매개 변수로 사용하면 일반 매개 변수를 판별 할 수없는 컴파일러가 혼동 될 수 있습니다.
Whyllee

예외는 어떻습니까? 비동기 메소드는 예외를 잡아서 리턴 된 태스크에 저장하는 상태 머신으로 컴파일됩니다. 이것은 첫 번째 대기 전에 코드 실행에도 발생합니다. Task.FromResult를 반환하는 메서드는 예외를 직접 throw 할 수 있습니다.
Robert Važan

@ RobertVažan 흥미로운 최신 사례입니다. 아마도 메소드에서 알려진 결과 를 검색 하고 해당 메소드에서 예외가 발생하면 수정이 필요한 결함이있는 것입니다.
Gusdor

1
@ RobertVažan 당신은 자신의 FromException메소드를 쉽게 작성할 수있다 FromResult. 이러한 메소드는 예외가 결과 태스크에 표시되는 것이 중요한 경우 오류 케이스에 대해 단순히이를 리턴 할 수 있습니다.
Servy

1
Task.FromException은 .NET 4.5에서 사용할 수 없습니다 ... 지정해야한다고 생각합니다.
STiLeTT

12

반환 값이없는 작업의 경우 .NET 4.6에 Task.CompletedTask 가 추가 되었습니다 .

이미 TaskStatus.RanToCompletion에있는 작업을 반환합니다. 매번 같은 인스턴스를 반환하지만 문서는 그 사실에 의존하지 말라고 경고합니다.



1

Calling Task. WhenAll 매개 변수없이 완료된 작업을 반환합니다.

Task task = Task.WhenAll();

이것이 작동하는 동안, 존재하지 않는 작업을 기다리는 것을 암시하는 코드를 읽을 때 사람들을 혼란스럽게하는 모호한 해결 방법
Adrian Hristov
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.