我正在使用WebClient类和我自己的瘦包装器来通过HTML请求JSON - 我正处于Comet类架构的接收端,因此客户端需要始终保持挂起的请求,这样服务器就可以随意推送到客户端。
我正在尝试确认以下代码是否是正确且安全的方法:
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();
根据我自己的分析,我认为上述内容将确保客户端在a)收到响应或b)超时时始终重新提交请求。这是否是实现这一目标的可接受方式,还是我错过了更好的做法?以这种方式使用while循环对我来说似乎是不标准的,但是我无法想到创建等待直到循环的任何其他方式。
我还想确保我不会使用此设置泄漏任何资源,因为它可能会或者可能不会每次都调用EndInvoke()吗?
答案 0 :(得分:1)
我担心递归调用最终会导致堆栈溢出。
如果你运行几秒钟,你会收到堆栈溢出错误......
Action<int> action = null;
action = new Action<int>((i) =>
{
Console.WriteLine("Hello {0}", i);
action(i+1);
});
action(1);
我到了12,181。你走了多远? :)
从代码的外观来看,您似乎并不需要调用WebClient的Async方法。事实上,调用直接下载方法可能比你所拥有的紧密循环更有效。
也许是这样的?
var uri = new Uri("http://www.google.com");
var client = new WebClient();
while(true)
{
try
{
var data = client.DownloadData(uri);
Console.WriteLine("Downloaded {0:N0} bytes.", data.Length);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
答案 1 :(得分:1)
当我过去构建HTTP Streaming库时,我使用了HttpWebRequest
类,因为它可以让您获得更多控制权。您可以在this code中找到与Twitter的HTTP Streaming API连接的示例。