Friday, May 4, 2012

Configuring WebClient Timeout and ConnectionLimit

Simplicity is nice, but not when it comes at the expense off accomplishing your goal.

Recently I have been using System.Net.WebClient to access some REST APIs. It is great how simple the WebClient class is to use, but unfortunately it does not natively support configuring it's timeout or connection limit. In fact, before I knew that the default connection limit was preventing me from making more than two concurrent requests at a time, it was actually causing me some serious issues while doing performance testing.

Good news, both of these issues are very easy to fix by simply extending the WebClient class.

Sample Class

public class ConfigurableWebClient : WebClient
{
    public int? Timeout { get; set; }
    public int? ConnectionLimit { get; set; }
        
    protected override WebRequest GetWebRequest(Uri address)
    {
        var baseRequest = base.GetWebRequest(address);
        var webRequest = baseRequest as HttpWebRequest;
        if (webRequest == null)
            return baseRequest;
 
        if (Timeout.HasValue)
            webRequest.Timeout = Timeout.Value;
 
        if (ConnectionLimit.HasValue)
            webRequest.ServicePoint.ConnectionLimit = ConnectionLimit.Value;
 
        return webRequest;
    }
}
kick it on DotNetKicks.com

Enjoy,
Tom

4 comments:

  1. Nice and simple solution! I'm just wondering if using nullable types here is a good idea. In .NET libraries "unlimited" is usually represented by 0 and so to be consistent it would seem a good idea to use ints instead of nullable ints.

    ReplyDelete
  2. I like it, but what about authentication?

    ReplyDelete
  3. Spurgius,
    This could use 0 instead of null, I guess I just like the way HasValue reads more a magic number like default(int).

    Marek,
    Authentication depends on the type of authentication that you are doing. Some might require custom headers, other you can just use the Credentials property:

    using (var webClient = new ConfigurableWebClient
    {
    ConnectionLimit = 5,
    Credentials = new NetworkCredential
    {
    UserName = "tdupont750",
    Password = "password"
    }
    })
    {
    // TODO
    }

    ReplyDelete
    Replies
    1. Thanks, I have just started creating WCF service and I want to call it from "normal" client like VFP/JavaScript/PHP (curl). Is this way good?

      Delete

Real Time Web Analytics