2011-09-15 3 views
14

TaskCompletionSource.SetResult(...)이 이미 호출 된 경우 TaskCompletionSource.Task에서 ContinueWith(...) 메서드를 사용하는 것이 안전합니까? task.ContinueWith가 설정되기 전에 WebClient.DownloadStringCompleted 이벤트가 이미 해고 경우TaskCompletionSource.Task에서 ContinueWith 메서드를 호출하는 것이 안전합니까? (즉, .SetResult가 호출되었습니다)?

// this was written inside the question box, please excuse any silly errors and lack of error checking (I'm not near VS right now)... 

private WebClient _webClient = new WebClient(); 

public Task<string> GetExamplePage() { 

    var tcs = new TaskCompletionSource<string>(); 

    web.DownloadStringCompleted += (s, ea) => tcs.SetResult(ea.Result); 

    web.DownloadStringAsync(new URI(@"http://www.example.com/example.html")); 

    return tcs.task; 
} 

public void ProcessExamplePage() { 

    var task = GetExamplePage(); 

    Thread.Sleep(1000); 

    task.ContinueWith(t => Console.WriteLine(t.Result)); // *line in question* 
} 

Console.WriteLine(...)가 실행 :

이 기본 코드 잘하면 문제를 프레임에 도움이 될 것입니다?

MSDN이 말을 (Task.ContinueWith)가 :

Task.ContinueWith 방법을

는 현재 작업이 완료 될 때까지 작업이 그것을 실행으로 인해 완료 여부, 실행을 스케줄 할 수없는 것입니다 반환

~ 완료, 처리되지 않은 예외로 인해 오류 발생 또는 취소로 인해 일찍 종료되는

불행히도이 메서드가 호출되고 작업이 이미 완료된 경우 어떻게되는지는 언급하지 않습니다.

제공 할 수있는 정보에 대해 미리 감사드립니다. :)

답변

17

예이 작업은 정상적으로 수행되어야합니다. ContinueWith는 이전 작업이 완료되었는지 확인하고, 그렇지 않으면 작업을 계속 대기열에 추가합니다.

+2

새로운 비동기 작업이 시작 되나요? 아니면 동기식으로 계속 진행 되나요? ''TaskCompletionSource''가 비동기 작업을 시작하지 않았기 때문에. – annemartijn

+0

니스. 이것에 관한 문서에 대한 언급은 훌륭 할 것입니다. –

+0

@annemartijn 원래 작업 (또는 연속)이 'TaskCreationOptions.RunContinuationsAsynchronously' (또는'TaskContinuationOptions. Run Continuations Asynchronously')를 지정하는지 여부에 달려 있습니다 - 이것은 연속 *에만 적용됩니다. - 그리고/또는 Continuation이 'TaskContinuationOptions.ExecuteSynchronously'을 지정하는지 여부 (이는 연속 자체에 적용됨). –

관련 문제