【发布时间】:2017-05-23 22:13:11
【问题描述】:
我正在使用异步操作来下载大文件 (>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),该应用程序不会挂起,因为我可以在视图之间切换并在下载期间触发 javascript 警报功能过程。
但是对于我的真实项目,不幸的是,应用程序挂起,直到下载完成。
在配置或其他方面有什么我应该考虑的吗?
有什么调试技巧可以查看它是如何在一个全新的应用程序上运行,而不是在我的实际项目上运行的吗?
【问题讨论】:
-
如果您需要任何帮助,您需要发布 GetLargeFile 的代码
-
Some code to read file & write it to response stream in loop使用异步 IO?向我们展示代码。 -
感谢您的回复。代码更新
-
您没有在异步方法中执行任何异步操作。如果异步方法从不等待,只需将方法标记为
async将绝对没有,并且该方法将同步运行。这是网络服务器上的坏 juju。将基于 Task 的异步方法与await一起用于所有 IO 交互。 -
@Raghu 为什么不自己试一试,如果遇到更多麻烦,请提出新问题?为了让您开始,您的第一个读取操作可能是
length = await iStream.ReadAsync(buffer, 0, 10000);。
标签: c# asp.net-mvc download async-await