服务文件作为ASP.NET MVC操作的一部分很慢

时间:2016-11-24 13:03:16

标签: asp.net asp.net-mvc file download

在我的ASP.Net MVC应用程序中,我有一个后端生成报告。生成报告后,用户可以使用链接调用报告来下载报告。但是,我觉得提供文件的动作有点慢(4到8秒),其他动作在比较中是即时的。

以下是执行服务的代码

// GET: /WS/Report/GetReport
[HttpGet]
public ActionResult GetReport(string fileName)
{
    string path = Path.Combine(_reportGeneratedPath, fileName);
    if (!System.IO.File.Exists(path))
        return XmlMessage.Error("Report does not exist");
     Response.ContentType = MimeMapping.GetMimeMapping(fileName);
     Response.AddHeader("Content-Disposition", String.Format("attachment; filename={0}", fileName));
     Response.AddHeader("Content-Length", new FileInfo(path).Length.ToString());

    Response.WriteFile(path);
    Response.End();
    return null;
}

PS:出于安全原因,我无法切换到直接文件访问。

2 个答案:

答案 0 :(得分:0)

System.IO.File.Exists会很慢,因为它是一个IO操作。为了加快操作速度,您可以使用MemoryCache实现缓存机制,MemoryCache是​​System.Runtime.Caching的一部分。另外,Response.WriteFile是一个同步操作,如果你切换到异步的Response.TransmitFile,它可能会改善你的响应时间。这种方法对你所拥有的只是一个小的渐进式改进,你也可以采用流媒体方法,这将涉及你所拥有的更多变化。

报告生成完成后,您将报告的完整路径添加到缓存中,然后您可以将Action方法修改为类似的东西(您可以随时改进缓存机制,我在这里有简单的实现,有关详细信息,请访问https://msdn.microsoft.com/en-us/library/system.runtime.caching.memorycache(v=vs.110).aspx

// GET: /WS/Report/GetReport
[HttpGet]
public ActionResult GetReport(string fileName)
{

    string path = Path.Combine(_reportGeneratedPath, fileName);
    var reportPathCache = MemoryCache.Default;
    if(!reportPathCache.Contains(path))
    {
      return XmlMessage.Error("Report does not exist");
    }
     Response.ContentType = MimeMapping.GetMimeMapping(fileName);
     Response.AddHeader("Content-Disposition", String.Format("attachment; filename={0}", fileName));
     Response.AddHeader("Content-Length", new FileInfo(path).Length.ToString());

    Response.Buffer = false;
    Response.TransmitFile(path);
    Response.End();
    return null;
}

答案 1 :(得分:0)

我已将其剥离为“裸露的骨头” ...将单个文件设置到内存中,然后与从IHttpModule下载它相比,从操作中下载它。由于某种原因(可能是MVC管道负载),IHttpModule的速度要快得多(对于较小的文件,例如产品列表图像)。我没有在路由中使用正则表达式(这会使速度更慢)。在IHttpModule中,我达到的速度与URL指向驱动器上的文件的速度相同(当然,如果文件位于驱动器上,而不是URL指向的驱动器位置)。