下载大文件时为什么我的异步操作会挂起?

时间:2017-05-23 11:39:36

标签: c# asp.net-mvc download async-await

我正在使用异步操作来下载大文件(> 500MB)。我的下面的代码挂起我的应用程序,直到文件下载完成。

public async Task<ActionResult> Download(string filePath, string fileName)
    {
        try
        {
            if(!string.IsNullOrEmpty(filePath))
            {
                filePath = Path.Combine(Code.Config.UploadFilesPath(), filePath);
                string contentType = MimeMapping.GetMimeMapping(fileName);

                if (System.IO.File.Exists(filePath))
                {
                    await GetLargeFile(filePath, fileName);
                }
                else
                {
                    return Content("Requested File does not exist");
                }
            }
        }
        catch(Exception ex) { }
        return Content("");
    }

private async Task GetLargeFile(string fullPath, string outFileName)
{
  System.IO.Stream iStream = null;

        // Buffer to read 10K bytes in chunk:
        byte[] buffer = new Byte[10000];

        // Length of the file:
        int length;

        // Total bytes to read:
        long dataToRead;

        // Identify the file to download including its path.
        string filepath = fullPath;

        // Identify the file name.
        string filename = System.IO.Path.GetFileName(filepath);

        try
        {
            // Open the file.
            iStream = new System.IO.FileStream(filepath, System.IO.FileMode.Open,
                        System.IO.FileAccess.Read, System.IO.FileShare.Read);


            // Total bytes to read:
            dataToRead = iStream.Length;

            Response.Clear();
            Response.ContentType = MimeMapping.GetMimeMapping(filename);
            Response.AddHeader("content-disposition", "attachment; filename=\"" + outFileName + "\"");
            Response.AddHeader("Content-Length", iStream.Length.ToString());

            // Read the bytes.
            while (dataToRead > 0)
            {
                // Verify that the client is connected.
                if (Response.IsClientConnected)
                {
                    // Read the data in buffer.
                    length = iStream.Read(buffer, 0, 10000);

                    // Write the data to the current output stream.
                    Response.OutputStream.Write(buffer, 0, length);

                    // Flush the data to the output.
                    Response.Flush();

                    buffer = new Byte[10000];
                    dataToRead = dataToRead - length;
                }
                else
                {
                    //prevent infinite loop if user disconnects
                    dataToRead = -1;
                }
            }
        }
        catch (Exception ex)
        {
            throw new ApplicationException(ex.Message);
        }
        finally
        {
            if (iStream != null)
            {
                //Close the file.
                iStream.Close();
            }
            Response.Close();
        }
}

奇怪的是,如果我在一个全新的Web应用程序上使用与上面相同的代码并下载一个大文件(大约1GB),那么该应用程序就不会挂起,因为我可以在Views&amp;在下载过程中触发javascript警报功能。

但是在我的真实项目中,应用程序会挂起,直到下载完成为止。

在配置或其他任何事情上我应该考虑什么?

任何调试提示,以了解它如何在全新的应用程序上工作,而不是在我的实际项目中?

1 个答案:

答案 0 :(得分:0)

在Web应用程序的上下文中,async仅允许服务请求的线程在进入等待状态时返回到线程池。如果线程正在积极地工作,例如将文件假脱机到响应中,那么它实际上与运行同步相同。

同样,在Web应用程序的上下文中,有一个请求和一个响应。客户端发出请求,服务器响应该请求。在这里,该响应是一个文件,所以异步与否,线程将被绑定直到响应完成。你不能&#34;返回&#34;从行动直到回复发送。

相关问题