Безопасно ли вызывать метод ContinueWith для TaskCompletionSource.Task (для которого был вызван .SetResult)? - PullRequest
18 голосов
/ 15 сентября 2011

Безопасно ли использовать метод ContinueWith(...) на TaskCompletionSource.Task, если TaskCompletionSource.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(...) выполняться, если событие WebClient.DownloadStringCompleted уже произошло до установки task.ContinueWith?

В MSDN сказано следующее ( Task.ContinueWith ):

Задача. Продолжение с методом

Возвращенное задание не будет запланировано для выполнения до текущее задание выполнено, завершено ли оно из-за завершение успешно, сбой из-за необработанного исключения, или преждевременный выход из-за отмены.

К сожалению, здесь не упоминается, что происходит, если этот метод вызывается и задача уже выполнена.

Заранее благодарим вас за любую информацию, которую вы можете предоставить! :)

Ответы [ 2 ]

18 голосов
/ 19 сентября 2011

Да, это должно быть хорошо, ContinueWith проверяет, завершено ли предыдущее задание или нет, если это так, оно немедленно поставит в очередь продолжение.

2 голосов
/ 31 января 2016

Если указанная задача уже выполнена к моменту вызова ContinueWith, синхронное продолжение будет выполняться в потоке, вызывающем ContinueWith.https://msdn.microsoft.com/en-us/library/dd321576(v=vs.110).aspx

...