Я реализую код из принятого ответа на этот вопрос а>. Теперь у меня возникла проблема, связанная с тем, что потоки остаются открытыми: приложение никогда не завершается.
Я думаю, что это может быть вызвано нижним из двух вхождений ThreadPool.RegisterWaitForSingleObject
ниже. Первый прослушивает завершение WebRequest или истечение времени ожидания. Второй прослушивает запрашиваемую отмену. Теперь мне интересно: второй когда-нибудь закончится, если не будет запрошена отмена, или он будет ждать вечно?
public static Task<WebResponse> GetResponseAsync(this WebRequest request, CancellationToken token)
{
if (request == null)
throw new ArgumentNullException("request");
bool timeout = false;
TaskCompletionSource<WebResponse> completionSource = new TaskCompletionSource<WebResponse>();
AsyncCallback completedCallback =
result =>
{
try
{
completionSource.TrySetResult(request.EndGetResponse(result));
}
catch (WebException ex)
{
if (timeout)
completionSource.TrySetException(new WebException("No response was received during the time-out period for a request.", WebExceptionStatus.Timeout));
else if (token.IsCancellationRequested)
completionSource.TrySetCanceled();
else
completionSource.TrySetException(ex);
}
catch (Exception ex)
{
completionSource.TrySetException(ex);
}
};
IAsyncResult asyncResult = request.BeginGetResponse(completedCallback, null);
if (!asyncResult.IsCompleted)
{
if (request.Timeout != Timeout.Infinite)
{
WaitOrTimerCallback timedOutCallback =
(object state, bool timedOut) =>
{
if (timedOut)
{
timeout = true;
request.Abort();
}
};
ThreadPool.RegisterWaitForSingleObject(asyncResult.AsyncWaitHandle, timedOutCallback, null, request.Timeout, true);
}
if (token != CancellationToken.None)
{
WaitOrTimerCallback cancelledCallback =
(object state, bool timedOut) =>
{
if (token.IsCancellationRequested)
request.Abort();
};
ThreadPool.RegisterWaitForSingleObject(token.WaitHandle, cancelledCallback, null, Timeout.Infinite, true);
}
}
return completionSource.Task;
}