抛出了System.OutOfMemoryException – WebClient.DownloadStringAsynch()

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

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

问:

  • 修复是什么?
  • 我怎么能使用HttpWebRequest并发送asynch作为webclient的替代?
  • 使用等待使用.net 4.5怎么样(与.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..."); } 

DownloadStringAsync将创建一个包含整个响应的巨型字符串。
如果你为了很多大回复而调用它,你将会耗尽内存。

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

如果你仍然想要asyncrony,你应该移动.Net 4.5,它增加了更容易使用的GetResponseAsync()方法(而不是旧的基于APM的BeginGetResponse()