Search code examples
c#httpwebrequestcancellation-token

c# abort async HttpWebRequest after timeout


I found here https://stackoverflow.com/a/19215782/4332018 a nice solution to use CancellationToken with async HttpWebRequest:

public static class Extensions
{
    public static async Task<HttpWebResponse> GetResponseAsync(this HttpWebRequest request, CancellationToken ct)
    {
        using (ct.Register(() => request.Abort(), useSynchronizationContext: false))
        {
            try
            {
                var response = await request.GetResponseAsync();
                return (HttpWebResponse)response;
            }
            catch (WebException ex)
            {
                // WebException is thrown when request.Abort() is called,
                // but there may be many other reasons,
                // propagate the WebException to the caller correctly
                if (ct.IsCancellationRequested)
                {
                    // the WebException will be available as Exception.InnerException
                    throw new OperationCanceledException(ex.Message, ex, ct);
                }

                // cancellation hasn't been requested, rethrow the original WebException
                throw;
            }
        }
    }
}

But I don't understand how I can abort request if it is performed longer than preset time.

I know about CancellationTokenSource() and CancelAfter(Int32), but don't understand how to modify the above example to use CancellationTokenSource, because it hasn't Register method.

How can I make a async HttpWebRequest with the possibility of cancellation after preset time?


Solution

  • When you create the token source, set the cancellation. Then pass in the token. It should timeout.

    CancellationTokenSource cts = new CancellationTokenSource();
                    cts.CancelAfter(1000);
    
                    var ct = cts.Token;
    
                    var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://www.zzz.com/here");
                    var test = Extensions.GetResponseAsync(httpWebRequest, ct);