简体   繁体   English

如何在超时或响应后不断打开WebClient请求

[英]How to keep a WebClient request constantly open after timeout or response

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. 我正在使用WebClient类和我自己的瘦包装器来通过HTML请求JSON - 我正处于类似Comet的架构的接收端,因此客户端需要始终保持挂起的请求,以便服务器可以随意推送到客户端。

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. 根据我自己的分析,我认为上述内容将确保客户端在a)收到响应或b)超时时始终重新提交请求。 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. 以这种方式使用while循环对我来说似乎是非标准的,但我想不出任何其他方式来创建等待直到循环。

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? 我还想确保我没有使用此设置泄漏任何资源,因为它可能会或可能不会每次都调用EndInvoke()吗?

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... 如果你运行这几秒钟,你会得到一个堆栈溢出错误...

Action<int> action = null;
action = new Action<int>((i) =>
{
    Console.WriteLine("Hello {0}", i);
    action(i+1);
});
action(1);

I got to 12,181. 我到了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. 从代码的外观来看,您实际上并不需要调用WebClient的Async方法。 In fact, calling the direct download method might be more efficient than the tight loop you have. 实际上,调用直接下载方法可能比您拥有的紧密循环更有效。

Perhaps something like this? 也许是这样的?

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);
    }
}

When I've built HTTP Streaming libraries in the past I've used the HttpWebRequest class as it gives you a bit more control. 当我在过去构建HTTP Streaming库时,我使用了HttpWebRequest类,因为它可以让你获得更多的控制权。 You can find an example in this code which connections to Twitter's HTTP Streaming API. 您可以在此代码中找到与Twitter的HTTP Streaming API连接的示例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM