Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Substitute for WebClient to Prevent Timeouts?

I'm working on a C# project that uses a public XML feed for calculations. I originally used XmlDocument.Load, but migrated to WebClient.DownloadString so I could include headers in my request. The feed I'm accessing usually responds quickly, but every now and again it fails to respond within the timeout period of the WebClient object, and I get an exception. Here's my code:

XmlDocument xmlDoc = new XmlDocument();

Webclient client = new WebClient();
client.Headers["User-Agent"] = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.202 Safari/535.1";
client.Headers["Accept"] = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";

string data = client.DownloadString(/*URL*/);

xmlDoc.LoadXml(data);

I've read that you cannot change the timeout property of WebClient, and people who have this problem should use HttpWebRequest instead. Unfortunately, I don't know how to go about implementing this in a way that still allows me to use my headers AND send that result to xmlDoc. Due to the nature of this application, I don't care how long it takes to receive the data; I can handle alerting the user.

What is the best way to go about doing this?

like image 537
Sonic42 Avatar asked Dec 04 '22 19:12

Sonic42


2 Answers

You could use a WebClient derived class for this, which just adds the timeout you want for each fetch:

public class TimeoutWebClient : WebClient
{
    protected override WebRequest GetWebRequest(Uri address)
    {
        HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(address);
        request.Timeout = 60000; //1 minute timeout
        return request;
    }
}

If you use TimeoutWebClient instead of WebClient now, you get the timeout behavior that you want. If the custom headers you need are the same for each request, you could add those here as well and your calling code remains very clean.

like image 158
BrokenGlass Avatar answered Dec 25 '22 22:12

BrokenGlass


XmlDocument xmlDoc = new XmlDocument();

HttpWebRequest request = new (HttpWebRequest)WebRequest.Create(/*URL*/);
request.Headers = new WebHeaderCollection();
// fill in request.Headers...

// The response is presented as a stream. Wrap it in a StreamReader that
// xmlDoc.LoadXml can accept.
xmlDoc.LoadXml(new StreamReader(request.GetResponse().GetResponseStream());
like image 38
Anders Abel Avatar answered Dec 25 '22 21:12

Anders Abel