Подтвердить что ты не робот

Web API 2 скачать файл с помощью async Задача <IHttpActionResult>

Мне нужно написать метод, подобный приведенному ниже, для возврата текстового документа (.txt, pdf,.doc,.docx и т.д.). Хотя есть хорошие примеры публикации файла в Web API 2.0 в Интернете, я не смог найти подходящий для его загрузки. (Я знаю, как это сделать в HttpResponseMessage.)

  public async Task<IHttpActionResult> GetFileAsync(int FileId)
  {    
       //just returning file part (no other logic needed)
  }

Нужно ли вообще быть асинхронным? Я только хочу вернуть поток. (Это нормально?)

Что еще важнее, прежде чем я закончу работу в одну сторону или другую, я хотел бы знать, что такое "правильный" способ выполнять такую ​​работу... (так подходы и методы, упоминающие это было бы очень полезно).. спасибо.

4b9b3361

Ответ 1

Правильно, для вашего вышеуказанного сценария действие не должно возвращать результат асинхронного действия. Здесь я создаю пользовательский IHttpActionResult. Вы можете проверить мои комментарии в приведенном ниже коде.

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 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);
    }
}

Ответ 2

Методы являются асинхронными, если возвращают объект Task, а не потому, что они украшены ключевым словом async. async - это только синтаксический сахар, который заменит этот синтаксис, что может стать довольно сложным, если больше задач объединены или больше продолжений:

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 всегда требует ожидания, это выполняется компилятором.

Обе реализации являются асинхронными, единственное отличие заключается в том, что async + ждет замещения расширяет ContinueWith на "синхронный" код.

Возвращаемая задача из методов контроллера, что делает IO (99% случаев, которые я оцениваю) важна, поскольку среда выполнения может приостанавливать и повторно использовать поток запросов для обслуживания других запросов во время выполнения операции ввода-вывода. Это снижает шансы исчерпать потоки пула потоков. Вот статья на тему: http://www.asp.net/mvc/overview/performance/using-asynchronous-methods-in-aspnet-mvc-4

Итак, ответ на ваш вопрос: "Нужно ли вообще быть асинхронным?" Я только хочу вернуть поток. (Это нормально?) "заключается в том, что он не имеет никакого значения для вызывающего, он изменяет только то, код выглядит (но не работает).