http post请求的多个异步流写入性能下降

时间:2014-09-04 14:37:02

标签: c# performance stream httpwebrequest async-await

最近我正在测试线程和异步/等待中的http“每秒请求数”差异。

使用Async / Await总是比线程(每秒2000-3000个请求)好一点(~30%),直到我将httpwebrequest从“GET”更改为“POST”

线程版本仍然正常(每秒约2000-3000个请求),线程数量很大,如2000线程

Async / Await版本变得很慢,甚至陷入大量的异步任务情况(每秒约500个请求,一些任务(~1%)没有完成(不合理的时间,如1分钟),尽管所有其他任务都已完成很早)

请对此有所了解,我几乎无法想到发生这种情况的原因。

这是卡住的功能

using (Stream postStream = await req.GetRequestStreamAsync())
{
    await postStream.WriteAsync(bytes, 0, bytes.Length); //This is the function that stuck in async version
}

这是我的测试代码

public static Amount = 0;
public void StartSync(int threadAmount)
{
            Amount = 0;
            Thread[] thread = new Thread[threadAmount];
            Stopwatch sw = new Stopwatch();
            sw.Start();
            for (int i = 0; i < thread.Length; i++)
            {
                thread[i] = new Thread(() =>
                {
                    SyncTest();
                });
                thread[i].IsBackground = true;
                thread[i].Start();
            }
            for (int j = 0; j < thread.Length; j++)
            {
                thread[j].Join();
            }
            sw.Stop();
            MessageBox.Show("Total requests: " + amount + "\r\nTotal seconds: " + (sw.ElapsedMilliseconds / 1000.0) + "\r\nRequests per second: " + Convert.ToDouble(amount) / (sw.ElapsedMilliseconds / 1000.0));
}
public void StartAsync(int threadAmount)
{
            Amount = 0;
            Task[] task = new Task[threadAmount];
            Stopwatch sw = new Stopwatch();
            sw.Start();
            for (int i = 0; i < threadAmount; i++)
            {
                task[i] = AsyncTest();
            }

            await Task.WhenAll(task);
            sw.Stop();
            MessageBox.Show("Total requests: " + amount + "\r\nTotal seconds: " + (sw.ElapsedMilliseconds / 1000.0) + "\r\nRequests per second: " + Convert.ToDouble(amount) / (sw.ElapsedMilliseconds / 1000.0));
}
public async Task<bool> AsyncTest()
{

            HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create("http://www.google-analytics.com/__utm.gif");
            req.Method = "POST";
            req.AllowAutoRedirect = false;
            byte[] bytes = Encoding.ASCII.GetBytes("test");
            req.ContentType = "application/x-www-form-urlencoded";
            req.ContentLength = bytes.Length;


            using (Stream postStream = await req.GetRequestStreamAsync())
            {
                await postStream.WriteAsync(bytes, 0, bytes.Length); //This is the function to be investigated. Adding this line slows down async side significantly
            }

            using (HttpWebResponse res = (HttpWebResponse)await req.GetResponseAsync())
            using (Stream responseStream = res.GetResponseStream())
            {
                StreamReader sr = new StreamReader(responseStream, Encoding.ASCII);
                string resp = await sr.ReadToEndAsync();
            }
            Amount++;
            return true;
}

public bool SyncTest()
{
            HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create("http://www.google-analytics.com/__utm.gif");
            req.Method = "POST";
            req.AllowAutoRedirect = false;
            byte[] bytes = Encoding.ASCII.GetBytes("test");
            req.ContentType = "application/x-www-form-urlencoded";
            req.ContentLength = bytes.Length;
            using (Stream oStreamOut = req.GetRequestStream())
            {
                oStreamOut.Write(bytes, 0, bytes.Length);
            }
            using (HttpWebResponse webResponse = (HttpWebResponse)req.GetResponse())
            {
                using (Stream responseStream = webResponse.GetResponseStream())
                {
                    StreamReader sr = new StreamReader(responseStream, Encoding.ASCII);
                    string resp = sr.ReadToEnd();
                }
            }
            Amount++;
            return true;
}

更新1:

我测试了具有大量异步任务的内存流中的WriteAsync,但没有发生减速

public async Task<bool> AsyncWrite()
{
    byte[] bytes = Encoding.ASCII.GetBytes("test");
    using (MemoryStream ms = new MemoryStream())
    {
        await ms.WriteAsync(bytes, 0, bytes.Length);
    }
}

更新2:

我插上了我的路由器,异步版本变得正常,不再卡住了。 只有连接路由器,才会发生奇怪的减速。 我无法解释为什么这只发生在异步版本而不是线程......

0 个答案:

没有答案