【问题标题】:Task was cancelled when trying to download file from WebApi尝试从 WebApi 下载文件时任务被取消
【发布时间】:2017-12-15 03:33:20
【问题描述】:

我在尝试从 Web API 下载 zip 文件时收到错误“任务已取消”。我做错了什么?

说明:在执行当前 Web 请求期间发生未处理的异常。请查看堆栈跟踪以获取有关错误及其源自代码的位置的更多信息。

异常详细信息:System.Threading.Tasks.TaskCanceledException:任务已取消。

using (var ms = new MemoryStream())
{
    using (var zipArchive = new ZipArchive(ms, ZipArchiveMode.Create, true))
    {
        foreach (var attachment in item)
        {
            var entry = zipArchive.CreateEntry(attachment.ItemAnalisado.Arquivo.Nome, CompressionLevel.Fastest);
            using (var stream = entry.Open())
            {
                var dadosArquivo = File.ReadAllBytes(
                Path.Combine(CaminhoImagens,
                attachment.ItemAnalisado.Arquivo.ProcessoId.ToString(),
                attachment.ItemAnalisado.Arquivo.SubPastaId.ToString(),
                attachment.ItemAnalisado.Arquivo.Id.ToString()));
                stream.Write(dadosArquivo, 0, dadosArquivo.Length);
                //stream.Position = 0;
                stream.Close();
            }
        }
    }
    HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
    ms.Position = 0;
    response.Content = new StreamContent(ms);
    ms.Dispose();
    response.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
    response.Content.Headers.ContentDisposition.FileName = "teste.zip";
    response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/zip");
    return response;
}

【问题讨论】:

  • 创建一个 zip 存档需要多长时间?可能任务因超时而被取消。
  • 你为什么在里面调用'stream.Close()'?它应该在块的末尾自动关闭。
  • 为什么设置响应内容后立即调用ms.Dispose()?

标签: c# asp.net .net asp.net-web-api asp.net-web-api2


【解决方案1】:

我在尝试下载调用我的 API 的 Excel 文件时遇到此错误。我没有在这个方法上实现 ATP,所以起初它很混乱。这是我的初始代码:

public IHttpActionResult Get([FromUri] string id, [FromUri] SurveyReportRequestType requestType) {
    byte[] excelData = System.Text.Encoding.UTF8.GetBytes("Boobs out!");
    HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
    using (var stream = new MemoryStream(excelData))
    {
        result.Content = new StreamContent(stream);
        result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
        result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
        {
            FileName = "Data.xls"
        };
    }
    return ResponseMessage(result);
}

在思考并做出一些改变之后:

...

byte[] excelData = System.Text.Encoding.UTF8.GetBytes("Boobs aout!");

HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
var stream = new MemoryStream(excelData);
result.Content = new StreamContent(stream);
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
    FileName = "Data.xls"
};
return ResponseMessage(result);

...

如您所见,我将 stream 包含在 using 语句中。这导致请求未完成,因为内容不可用于响应。

【讨论】:

  • 简而言之:NOT 在控制器中处理内容流。 Web API 会处理它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-08
  • 1970-01-01
  • 2017-10-22
  • 2020-10-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多