2010-11-22 2 views
100

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

private readonly Result theResult = new Result(); 

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

더 나은 솔루션이 있습니까 :

이것은 내가 현재하고있어 무엇인가? .NET 4.5을 대상으로하는 경우

+6

참고,이 질문에 대한 답변은 작업 때문에 상속 작업에서 일반 작업 (NO )를 만들기 위해 잘 작동합니다. –

답변

102
private readonly Result theResult = new Result(); 

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

당신이 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); 

.NET 4.6 Task.CompletedTask 추가 일반 Task. .NET의 이전 버전에 대한

public static Task CompletedTask { get; } 

해결 방법을 :

  • 비동기 표적으로 팩 (또는 AsyncCTP)와 .NET 4.0을 대상으로 대신 TaskEx.FromResult를 사용할 수 있습니다.

  • Task 전에 .NET 4.6에, 당신은 Task<T>Task에서 파생 그냥 Task.FromResult<object>(null) 또는 Task.FromResult(0)를 호출 사실을 사용할 수있는 제네릭이 아닌 얻으려면.

+13

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

+0

예외는 무엇입니까? 비동기 메서드는 예외를 catch하고 반환 된 작업에 저장하는 상태 시스템으로 컴파일됩니다. 이것은 첫 번째 기다리기 전에 실행되는 코드에 대해서도 발생합니다. Task.FromResult를 반환하는 메서드는 예외를 직접 throw 할 수 있습니다. –

+0

@ RobertVažan 흥미로운 엣지 케이스. 대체로 메서드에서 _known result_를 검색하고 그 메서드가 예외를 throw하는 경우 수정이 필요한 결함이 있습니다. – Gusdor

1

Rx를 사용하는 경우 대안은 Observable.Return (result) .ToTask()입니다.

12

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

TaskStatus.RanToCompletion에 이미있는 작업을 반환합니다. 아마도 매번 동일한 인스턴스를 반환 할 것이지만, 설명서에는 그 사실을 믿지 말라고 경고합니다.

0

매개 변수없이 Task.WhenAll을 호출하면 완료된 작업이 반환됩니다.

Task task = Task.WhenAll();