如何在超时或响应后保持WebClient请求持续打开

本文关键字:WebClient 请求 超时 响应 | 更新日期: 2023-09-27 18:18:43

我正在使用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循环对我来说似乎不标准,但是我想不出任何其他方法来创建wait-until类型的循环。

我还想确保我不泄漏任何资源与此设置,因为它可能或可能不保证EndInvoke()每次调用?

如何在超时或响应后保持WebClient请求持续打开

我担心递归调用最终会导致堆栈溢出。

如果你运行这几秒钟,你会得到一个堆栈溢出错误…

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

当我在过去构建HTTP流库时,我使用HttpWebRequest类,因为它给了你更多的控制。您可以在此代码中找到一个连接到Twitter的HTTP流媒体API的示例。