【问题标题】:Filehandler download interrupts + session is gone文件处理程序下载中断+会话消失
【发布时间】:2012-06-27 11:20:58
【问题描述】:

我编写了一个 ashx 处理程序,它以安全的方式将文件流式传输到浏览器,我希望授权用户访问这些文件。

问题是当我处理大文件 (+40 MB) 时,会话消失了 + 浏览器下载在 ~40 MB 后突然中断。

我已将 web.config 配置为在 240 分钟之前不超时。

在本地测试它不会给我同样的问题,在我的共享主机上测试它会。

谁能指出我正确的方向?

我尝试过使用和不使用 Reponse.Clear()

public void ProcessRequest(HttpContext context)
    {
        int id;

        if (new Core.SecurityManager().CurrentUser != null)
        {

            try
            {
                id = Convert.ToInt32(context.Request.QueryString["id"]);
            }
            catch
            {
                throw new ApplicationException("id could not  be parsed.");
            }

            string filename = new DocumentFactory().SelectDocumentById(id).Filename;

            string filePath = context.Server.MapPath("~/uploads/" + filename);

            //context.Response.Clear();

            context.Response.AddHeader("content-disposition", "attachment; filename=" + filename);

            context.Response.ContentType = "application/octet-stream";

            context.Response.WriteFile(filePath);

            //context.Response.Flush();

            //context.Response.End();
        }
        else
        {
            throw  new AuthenticationException();
        }

    }

Web.config:

 <sessionState mode="InProc" cookieless="false" timeout="240"></sessionState>

编辑尝试了以下,但仍然下载中断:

FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);

            byte[] byteArray = new byte[fs.Length];

            using (MemoryStream ms = new MemoryStream(byteArray))
            {
                long dataLengthToRead = ms.Length;
                int blockSize = dataLengthToRead >= 5000 ? 5000 : (int)dataLengthToRead;
                byte[] buffer = new byte[dataLengthToRead];
                context.Response.Clear();


                // Clear the content of the response
                context.Response.ClearContent();
                context.Response.ClearHeaders();


                // Buffer response so that page is sent
                // after processing is complete.
                context.Response.BufferOutput = true;


                // Add the file name and attachment,
                // which will force the open/cance/save dialog to show, to the header
                context.Response.AddHeader("Content-Disposition", "attachment; filename=" + filename);


                // bypass the Open/Save/Cancel dialog
                //Response.AddHeader("Content-Disposition", "inline; filename=" + doc.FileName);


                // Add the file size into the response header
                context.Response.AddHeader("Content-Length", fs.Length.ToString());


                // Set the ContentType
                context.Response.ContentType = "application/octet-stream";


                // Write the document into the response
                while (dataLengthToRead > 0 && context.Response.IsClientConnected)
                {
                    Int32 lengthRead = ms.Read(buffer, 0, blockSize);
                    context.Response.OutputStream.Write(buffer, 0, lengthRead);
                    //Response.Flush();
                    dataLengthToRead = dataLengthToRead - lengthRead;
                }

                context.Response.Flush();
                context.Response.Close();
            }


            // End the response
            context.Response.End();

通过添加完整路径通过浏览器直接访问文件时,下载什么都没有问题。

【问题讨论】:

    标签: asp.net ashx


    【解决方案1】:

    虽然在 IIS 中传递大文件的正确方法是以下选项,

    1. 在 WebLimits 中将 MinBytesPerSecond 设置为零(这肯定有助于提高性能,因为 IIS 会选择关闭持有 KeepAlive 连接的客户端以进行较小的传输)

    2. Allocate More Worker Process 到 Application Pool,我设置为 8,现在只有当你的服务器分发更大的文件时才应该这样做。这肯定会导致其他站点的运行速度变慢,但这将确保更好的交付。我们设置为 8,因为此服务器只有一个网站,而且它只提供大量文件。

    3. 关闭应用程序池回收

    4. 关闭会话

    5. 保持缓冲开启

    6. 在以下每个步骤之前,检查 Response.IsClientConnected 是否为真,否则放弃并且不发送任何内容。

    7. 在发送文件前设置 Content-Length

    8. 刷新响应

    9. 写入输出流,并定期刷新

    【讨论】:

    • 步骤 1 到 3 不可行,因为我在共享主机上,有限的 IIS 设置对我开放。第 4 步:我需要会话。
    • stackoverflow.com/questions/7948316/… 访问此链接。这可能会对您有所帮助。
    • support.microsoft.com/kb/812406 也访问这个。这也与您的问题有关。希望这一切对你有所帮助。 :-)
    • Response.TransmitFile() 做到了,谢谢 Krishanu,非常感谢!
    猜你喜欢
    • 2012-07-22
    • 2010-09-30
    • 2018-01-14
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多