gog
gog

Reputation: 12988

WebClient not respecting timeout policy

Im making a GET request using the WebClient class in .NET I make a custom webclient which overrides some properties and methods:

 public class CustomWebClient : WebClient
{
    public CookieContainer Cookies { get; private set; }
    public int Timeout { get; set; }
    public bool KeepAlive { get; set; }
    public Uri ResponseUri { get; private set; }

    public CustomWebClient()
    {
        Timeout = 30000;
        Cookies = new CookieContainer();
    }

    protected override WebRequest GetWebRequest(Uri address)
    {
            var request = base.GetWebRequest(address) as HttpWebRequest;

            if (request == null)
            {
                return base.GetWebRequest(address);
            }

            request.ContinueTimeout = 30000;
            request.KeepAlive = KeepAlive;
            request.Timeout = Timeout;
            request.CookieContainer = Cookies;
            return request;
    }

    protected override WebResponse GetWebResponse(WebRequest request)
    {
        var response = base.GetWebResponse(request);
        ResponseUri = response.ResponseUri;

        return response;
    }

    protected override WebResponse GetWebResponse(WebRequest request, IAsyncResult result)
    {
        var response = base.GetWebResponse(request, result);
        ResponseUri = response.ResponseUri;

        return response;
    }
}

Then in my client class I make a simple GET request:

 private async Task RenewIpAddress(CustomWebClient client)
 {
        var watch = Stopwatch.StartNew();
        try
        {
            client.KeepAlive = false;
            await   client.DownloadStringTaskAsync("http://someexternalwebsite");
            client.KeepAlive = true;
        }
        catch (Exception ex) // When throws a 'The remote server returned an error: (504) Gateway Timeout.' the elapsedTime is 5 minutes
        {
            watch.Stop();

            var elapsedTime = watch.ElapsedMilliseconds;
            Debug.WriteLine("RenewIpAddress:" + TimeSpan.FromMilliseconds(elapsedTime));
            throw;
        }
    }

Sometimes the elapsedTime is 5 minutes. I would like to kill this request before. It should be the TimeOut property job, but it seems not working for some cases. I have an internal HAProxy as a proxy to make this request. Where I can control this timeout?

EDIT:
The thrown exception is The remote server returned an error: (504) Gateway Timeout.

Upvotes: 1

Views: 407

Answers (1)

comwrg
comwrg

Reputation: 41

You can use Task to realize. like this

using System;
using System.Xml;
using System.Net;
using System.Text;
using System.IO;
using System.Threading;
using System.Threading.Tasks;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            CancellationTokenSource cts = new CancellationTokenSource();
            Task task = Task.Factory.StartNew((() =>
                                   {
                                       Console.WriteLine("start");
                                       Thread.Sleep(10000); // your code
                                       Console.WriteLine("end");
                                       if (cts.IsCancellationRequested) return;
                                   }), cts.Token);
            cts.CancelAfter(1000);
            Console.WriteLine("task has been canceled");
            Console.ReadKey();
        }
    }
}

Upvotes: 1

Related Questions