首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用异步Task<IHttpActionResult>的WebAPI2下载文件

使用异步Task<IHttpActionResult>的WebAPI2下载文件
EN

Stack Overflow用户
提问于 2014-02-04 00:54:54
回答 2查看 28.8K关注 0票数 22

我需要写一个像下面这样的方法来返回一个文本文档(.txt,pdf,.doc,.docx等)虽然在Web API2.0中有很好的例子可以在web上发布文件,但我找不到一个相关的只下载一个。(我知道如何在HttpResponseMessage中执行此操作。)

代码语言:javascript
复制
  public async Task<IHttpActionResult> GetFileAsync(int FileId)
  {    
       //just returning file part (no other logic needed)
  }

上面的内容需要异步吗?我只想返回流。(这样可以吗?)

更重要的是,在我以某种方式完成这项工作之前,我想知道做这类工作的“正确”方式是什么……(所以提到这一点的方法和技术将非常受欢迎)..谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-02-07 01:06:23

对,对于上面的场景,操作不需要返回异步操作结果。在这里,我创建了一个自定义的IHttpActionResult。你可以在下面的代码中查看我的评论。

代码语言:javascript
复制
public IHttpActionResult GetFileAsync(int fileId)
{
    // NOTE: If there was any other 'async' stuff here, then you would need to return
    // a Task<IHttpActionResult>, but for this simple case you need not.

    return new FileActionResult(fileId);
}

public class FileActionResult : IHttpActionResult
{
    public FileActionResult(int fileId)
    {
        this.FileId = fileId;
    }

    public int FileId { get; private set; }

    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        HttpResponseMessage response = new HttpResponseMessage();
        response.Content = new StreamContent(File.OpenRead(@"<base path>" + FileId));
        response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");

        // NOTE: Here I am just setting the result on the Task and not really doing any async stuff. 
        // But let's say you do stuff like contacting a File hosting service to get the file, then you would do 'async' stuff here.

        return Task.FromResult(response);
    }
}
票数 40
EN

Stack Overflow用户

发布于 2015-01-03 06:04:59

如果返回一个Task对象,则方法是异步的,而不是因为使用async关键字来修饰。异步只是替换这种语法的语法糖,当有更多的任务组合或更多的延续时,这种语法可能会变得相当复杂:

代码语言:javascript
复制
public Task<int> ExampleMethodAsync()
{
    var httpClient = new HttpClient();

    var task = httpClient.GetStringAsync("http://msdn.microsoft.com")
        .ContinueWith(previousTask =>
        {
            ResultsTextBox.Text += "Preparing to finish ExampleMethodAsync.\n";

            int exampleInt = previousTask.Result.Length;

            return exampleInt;
        });

    return task;
}

带有异步的原始样本:http://msdn.microsoft.com/en-us/library/hh156513.aspx

异步总是需要等待,这是由编译器强制执行的。

这两种实现都是异步的,唯一的区别是async+await替换将ContinueWith扩展为“同步”代码。

从控制器方法返回任务I/O(我估计99%的情况下)很重要,因为运行时可以挂起请求线程,并在IO操作进行时重用请求线程来服务其他请求。这降低了线程池线程耗尽的可能性。这里有一篇关于这个主题的文章:http://www.asp.net/mvc/overview/performance/using-asynchronous-methods-in-aspnet-mvc-4

所以你的问题的答案是“上面的代码需要异步吗?我只想返回流。(可以吗?)”它对调用者没有任何影响,它只会改变代码的外观(但不会改变它的工作方式)。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21533022

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档