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)
}
Нужно ли вообще быть асинхронным?
Я только хочу вернуть поток. (Это нормально?)
Что еще важнее, прежде чем я закончу работу в одну сторону или другую, я хотел бы знать, что такое "правильный" способ выполнять такую работу... (так подходы и методы, упоминающие это было бы очень полезно).. спасибо.
Ответы
Ответ 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
Итак, ответ на ваш вопрос: "Нужно ли вообще быть асинхронным?" Я только хочу вернуть поток. (Это нормально?) "заключается в том, что он не имеет никакого значения для вызывающего, он изменяет только то, код выглядит (но не работает).