并发请求的ASP.NET(或IIS?)行为

时间:2012-03-24 08:46:19

标签: asp.net-mvc-3 azure iis-7.5

我正在使用ASP.NET MVC3开发Web服务。 HTTP API的一种方法从POST请求的主体接收图像,并需要将其存储在磁盘上以供进一步处理。 方法的开头是这样的:

Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();

Interlocked.Increment(ref _generateCount);

byte[] fileBuffer;
using (Stream inputStream = Request.InputStream)
{
    if (inputStream.Length == 0)
    {
        Trace.WriteLine("Submitted file is empty", "Warning");
        inputStream.Close();
        Interlocked.Decrement(ref _generateCount);
        return new HttpStatusCodeResult(400, "Content is empty");
    }

    fileBuffer = new byte[inputStream.Length];
    inputStream.Read(fileBuffer, 0, (int)inputStream.Length);
    inputStream.Close();
}
stopwatch.Stop()
... (storing the fileBuffer on disk & quite CPU intensive processing on the file)

我正在一个小型Azure实例中托管该服务。

现在我的奇怪行为是当我向服务发出并行请求时。 假设我发出第一个请求,并在5秒后发出第二个请求。如你所见,我正在使用秒表来监控性能。对于第一个请求,ElapsedTime将非常小(小于一秒),但对于第二个请求,它通常读取大约。 14秒!

请注意,单个请求的平均处理时间约为。 25秒(当处理多个请求时达到40+),所以我在14秒后读取输入流,尽管第一个请求尚未完成。

我如何解释这种延迟?

由于

1 个答案:

答案 0 :(得分:1)

如果您的最终目标是将文件存储在磁盘上,为什么要将其加载到内存中?您可以直接写入输出流:

public ActionResult SomeAction()
{
    var stopwatch = Stopwatch.StartNew();
    if (Request.InputStream.Length == 0)
    {
        return new HttpStatusCodeResult(400, "Content is empty");
    }

    var filename = Server.MapPath("~/app_data/foo.dat");
    using (var output = System.IO.File.Create(filename))
    {
        Request.InputStream.CopyTo(output);
    }
    stopwatch.Stop();

    ...
}

另请注意,如果您发出2个尝试写入服务器上同一文件的并发请求,则可能会因为无法同时写入同一文件而导致数据或错误损坏。