在ASP.NET C#中下载大文件异步

时间:2015-06-11 13:40:50

标签: c# asp.net asynchronous large-files large-file-support

我有下面的代码适用于小文件,但对于大文件,它会根据需要生成zip,但不会下载它。我得到各种各样的错误,包括Timeout(我已设法解决)。另一个问题是它在同步中运行。我自己生成的最大文件是一个330MB的zip文件,附有大约30个高清图像。但这甚至可以用于GB,因为用户可以选择一次下载大约100张甚至更多的高清图像。

要解决这两个问题,我认为在async下载可能对两种情况都有帮助。我想提醒用户他们的下载已经开始,并且在准备就绪时会通知他们。

如果客户端IsConnected(然后删除文件)或发送电子邮件要求他们下载文件(如果他们已决定退出)(然后使用离线删除文件),我正在考虑向下发送流下载链接)。我只是不知道在哪里或如何编写async代码,或者如果用户决定退出,我实际上可以做什么。

这是我目前的代码:

private void DownloadFile(string filePath)
{
    FileInfo myfile = new FileInfo(filePath);

    // Checking if file exists
    if (myfile.Exists)
    {
        // Clear the content of the response
        Response.ClearContent();

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

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

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

        Response.TransmitFile(filePath);
        Response.Flush();

        try
        {
            myfile.Delete();
        }
        catch { }
    }
}

1 个答案:

答案 0 :(得分:0)

我不知道asp.net应用程序的异步下载,所以我无法解决这个问题。但是我遇到了足够的下载问题,总是从同一个地方开始。

首先,从通用句柄(ASHX)下载而不是Web表单。 webform希望在请求结束时执行额外的处理,这可能会导致问题。如果您使用的是Web表单或通用处理程序,那么您的问题并没有说明。

其次,始终使用ApplicationInstance.CompleteRequest()方法调用结束请求。不要使用Request.Close()或Request.End()

这两项更改经常为我清理下载问题。尝试这些更改,看看你是否得到相同的结果。即使您获得相同的结果,这也是一种更好的下载编码方式。

最后,顺便说一句,只在try-catch bock中捕获适当的异常。

您的代码将是这样的:

public class Handler1 : IHttpHandler
{

    public void ProcessRequest(HttpContext context)
    {
        // set from QueryString
        string filePath = "...";

        FileInfo myfile = new FileInfo(filePath);

        // Checking if file exists
        if (myfile.Exists)
        {
            // Clear the content of the response
            context.Response.ClearContent();

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

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

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

            context.Response.TransmitFile(filePath);
            context.Response.Flush();

            HttpContext.Current.ApplicationInstance.CompleteRequest();

            try
            {
                myfile.Delete();
            }
            catch (IOException)
            { }
        }
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}