Преобразование async / await в Task.ContinueWith

Этот вопрос был вызван комментариями кэтот:

Как сделать бэкпорт нелинейнымasync/await код для .NET 4.0 безMicrosoft.Bcl.Async?

В связанном вопросе у нас естьWebRequest операцию, которую мы хотим повторить ограниченное количество раз, если она продолжает терпеть неудачу.Async/await код может выглядеть так:

async Task<HttpWebResponse> GetResponseWithRetryAsync(string url, int retries)
{
    if (retries < 0)
        throw new ArgumentOutOfRangeException();

    var request = WebRequest.Create(url);
    while (true)
    {
        WebResponse task = null;
        try
        {
            task = request.GetResponseAsync();
            return (HttpWebResponse)await task;
        }
        catch (Exception ex)
        {
            if (task.IsCanceled)
                throw;

            if (--retries == 0)
                throw; // rethrow last error

            // otherwise, log the error and retry
            Debug.Print("Retrying after error: " + ex.Message);
        }
    }
}

С первой мысли, я бы использовалTaskCompletionSource, как то так (не проверено):

Task<HttpWebResponse> GetResponseWithRetryAsync(string url, int retries)
{
    if (retries < 0)
        throw new ArgumentOutOfRangeException();

    var request = WebRequest.Create(url);

    var tcs = new TaskCompletionSource<HttpWebResponse>();

    Action<Task<WebResponse>> proceesToNextStep = null;

    Action doStep = () =>
        request.GetResponseAsync().ContinueWith(proceedToNextStep);

    proceedToNextStep = (prevTask) =>
    {
        if (prevTask.IsCanceled)
            tcs.SetCanceled();
        else if (!prevTask.IsFaulted)
            tcs.SetResult((HttpWebResponse)prevTask.Result);
        else if (--retries == 0)
            tcs.SetException(prevTask.Exception);
        else
            doStep();
    };

    doStep();

    return tcs.Task;
}

Вопрос в том,как это сделать безTaskCompletionSource?

Ответы на вопрос(1)

Ваш ответ на вопрос