我正在使用异步操作来下载大文件(> 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警报功能。
但是在我的真实项目中,应用程序会挂起,直到下载完成为止。
在配置或其他任何事情上我应该考虑什么?
任何调试提示,以了解它如何在全新的应用程序上工作,而不是在我的实际项目中?
答案 0 :(得分:0)
在Web应用程序的上下文中,async仅允许服务请求的线程在进入等待状态时返回到线程池。如果线程正在积极地工作,例如将文件假脱机到响应中,那么它实际上与运行同步相同。
同样,在Web应用程序的上下文中,有一个请求和一个响应。客户端发出请求,服务器响应该请求。在这里,该响应是一个文件,所以异步与否,线程将被绑定直到响应完成。你不能&#34;返回&#34;从行动直到回复发送。