I am using the WebClient class and my own thin wrapper around it to request JSON over HTML — I am on the recieving end of a Comet-like architecture and so the client needs to keep a pending request open at all times, so that the server can push to the client at will.
I am trying to confirm whether the following code would be a correct and safe way to do this:
subscriber = new Action(() =>
{
// This function wraps the WebClient 'DownloadStringAsync' method
client.BeginDownload(this.Path, new AsyncCallback(x =>
{
var data = (x.AsyncState as Func<JsonResponse>).EndInvoke(x);
if (data != null)
{
OnReceive(data, new Uri(this.FullUri));
}
subscriber(); // Received data so re-submit request
}), this.QueryArgs);
while (client.IsBusy)// As long as busy, no need to re-submit a request
{
}
subscriber();
});
subscriber();
From my own analysis it looks to me like the above would ensure that the client always re-submits a request either when a) it receives a response, or b) it times out. Would this be an acceptable way to achieve this or is there a much better practice I am missing out on? Using the while-loop in this way seems nonstandard to me, however I can’t think of any other way to create a wait-until sort of loop.
I also want to make sure I don’t leak any resources with this setup, since it may or may not gaurantee that EndInvoke() is called every time?
I would be concerned that the recursive calls will eventually cause a stack overflow.
If you run this for a few seconds, you’ll get a stack overflow error…
I got to 12,181. How far did yours go? 🙂
From the look of your code, it seems that you don’t actually need to call the Async method of WebClient. In fact, calling the direct download method might be more efficient than the tight loop you have.
Perhaps something like this?