这个问题是由此问题的评论引起的:
如果没有使用
在链接的问题中,我们有一个
问题是,如何在不使用
如果没有使用
Microsoft.Bcl.Async
,如何将非线性async/await
代码回退到.NET 4.0?在链接的问题中,我们有一个
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
的情况下完成此操作?
GetResponseAsync
方法,您需要使用较旧的BeginGetResponse
/EndGetResponse
方法。 - Mike Zboray