1

私は貧弱なロード テスターを書いており、リソース (スレッド プール) を正しく管理していると思っていましたが、次のコードを実行すると、WebClient.DownloadStringAsynch への呼び出しで OutOfMemoryException が発生します。

.net4.0 を使用していますが、4.5 に移行できます。

質問:

  • 修正は何ですか?
  • HttpWebRequest を使用して、その非同期を webclient の代わりに送信するにはどうすればよいですか?
  • await を使用して .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...");
    
    }
    
4

1 に答える 1

3

DownloadStringAsync応答全体を含む単一の巨大な文字列を作成します。
大量の大きな応答に対してそれを呼び出すと、メモリが不足します。

代わりに、直接使用する必要がありますHttpWebRequest
そのGetResponse()(またはBeginGetResponse())メソッドは、メモリにバッファリングせずにサーバーから直接応答を読み取ることができる ストリームを提供します。

それでも非同期が必要な場合は、.Net 4.5 を移動する必要があります。これにより、使いやすいGetResponseAsync()方法が追加されます (古い APM ベースのBeginGetResponse().

于 2013-03-01T17:33:01.940 に答える