1

我正在编写一个糟糕的负载测试器,我认为我正在正确管理我的资源(线程池),但是当我运行以下代码时,我在调用 WebClient.DownloadStringAsynch 时收到了 OutOfMemoryException。

使用 .net4.0 但可以迁移到 4.5。

问:

  • 解决方法是什么?
  • 我如何使用 HttpWebRequest 并发送该异步作为 webclient 的替代方案?
  • 使用 .net 4.5 使用 await 怎么样(与 .net4 如何通过异步调用管理线程有什么区别?

    static void Main(string[] args)
    {
        System.Net.ServicePointManager.DefaultConnectionLimit = 200;
        while (true)
        {
            for (int i = 0; i < 100; i++)
            {
                Task.Factory.StartNew(LoadTestAsynchNET40);
            }
            Console.WriteLine(".........................sleeping...............................");
            Thread.Sleep(2);
        }
    }
    
    static void LoadTestAsynchNET40()
    {
      string url = "http://mysrv.com/api/dev/getthis?stuff=thestuff" + "&_=" + DateTime.Now.Ticks;  // <--- somtimes throws here...
        using (var client = new WebClient())
        {
            DateTime dt1 = DateTime.Now;
            client.Headers["Accept"] = "text/xml";
            client.DownloadStringCompleted += DownloadStringCompleted;
            Console.WriteLine(DateTime.Now.ToString("ss:fff") + ", Sent Ad Request...");
            client.DownloadStringAsync(new Uri(url), dt1); //<---throws here...
        }
    }
    
    static void DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
    {
        Console.WriteLine("Received reponse...");
    
    }
    
4

1 回答 1

3

DownloadStringAsync将创建一个包含整个响应的巨型字符串。
如果您将其称为大量响应,那么您将耗尽内存。

相反,您应该HttpWebRequest直接使用。
它的GetResponse()(或BeginGetResponse())方法为您提供了一个,允许您直接从服务器读取响应,而无需将其缓冲在内存中。

如果您仍然想要异步,您应该移动 .Net 4.5,它添加了更易于使用的GetResponseAsync()方法(相对于旧的基于 APM 的方法BeginGetResponse()

于 2013-03-01T17:33:01.940 回答