Возврат Void в асинхронном методе из контроллера WEB API

У меня есть этот асинхронный метод внутри ASP.NET MVC 4 WEB API Controller, который я получил из этого блога: http://www.strathweb.com/2012/04/html5-drag-and-drop-asynchronous-загрузканесколькихфайловспомощьюasp-net-webapi/

  public async Task<IList<RecivedFile>> Post()
    {
        List<RecivedFile> result = new List<RecivedFile>();
        if (Request.Content.IsMimeMultipartContent())
        {
            try
            {
                MultipartFormDataStreamProvider stream = new MultipartFormDataStreamProvider(HostingEnvironment.MapPath("~/USER-UPLOADS"));

                IEnumerable<HttpContent> bodyparts = await Request.Content.ReadAsMultipartAsync(stream);
                IDictionary<string, string> bodyPartFiles = stream.BodyPartFileNames;
                IList<string> newFiles = new List<string>();

                foreach (var item in bodyPartFiles)
                {
                    var newName = string.Empty;
                    var file = new FileInfo(item.Value);

                    if (item.Key.Contains("\""))
                        newName = Path.Combine(file.Directory.ToString(), item.Key.Substring(1, item.Key.Length - 2));
                    else
                        newName = Path.Combine(file.Directory.ToString(), item.Key);

                    File.Move(file.FullName, newName);
                    newFiles.Add(newName);
                }

                var uploadedFiles = newFiles.Select(i =>
                {
                    var fi = new FileInfo(i);
                    return new RecivedFile(fi.Name, fi.FullName, fi.Length);
                }).ToList();

                result.AddRange(uploadedFiles);
            }
            catch (Exception e)
            {
            }
        }
        return result;
    }

Мой вопрос: почему именно этот метод имеет возвращаемый тип Task? Не понятно "куда" или "кому" возвращает эту задачу? Как будто никто не ждет/получает возвращенный объект.

Интересно, каковы будут последствия, если я верну void следующим образом:

ИЗМЕНИТЬ:

Я попробовал приведенный ниже код, и он полностью сломал программу. это похоже на то, что среда выполнения теряет ссылку на код, сам код не завершает работу.

    public async void Post()
    {
        List<RecivedFile> result = new List<RecivedFile>();
        if (Request.Content.IsMimeMultipartContent())
        {
            try
            {
                MultipartFormDataStreamProvider stream = new MultipartFormDataStreamProvider(HostingEnvironment.MapPath("~/USER-UPLOADS"));

                IEnumerable<HttpContent> bodyparts = await Request.Content.ReadAsMultipartAsync(stream);
                IDictionary<string, string> bodyPartFiles = stream.BodyPartFileNames;
                IList<string> newFiles = new List<string>();

                foreach (var item in bodyPartFiles)
                {
                    var newName = string.Empty;
                    var file = new FileInfo(item.Value);

                    if (item.Key.Contains("\""))
                        newName = Path.Combine(file.Directory.ToString(), item.Key.Substring(1, item.Key.Length - 2));
                    else
                        newName = Path.Combine(file.Directory.ToString(), item.Key);

                    File.Move(file.FullName, newName);
                    newFiles.Add(newName);
                }

            }
            catch (Exception e)
            {
            }
        }

    }

person user1561202    schedule 11.08.2012    source источник


Ответы (3)


Среда выполнения ASP.NET ожидает его. Вы можете найти это видео полезным.

Большинство примеров для async предполагают контекст пользовательского интерфейса. ASP.NET также предоставляет контекст, но это контекст "запроса". - по одному на каждый HTTP-запрос. Мой async/await пост дает обзор этого "контекста" , а async/await FAQ — в гораздо подробнее.

person Stephen Cleary    schedule 11.08.2012
comment
Таким образом, вывод состоит в том, чтобы никогда не возвращать void в асинхронных методах при использовании в ASP.NET. - person user1561202; 13.08.2012
comment
В ASP.NET 4.5 есть несколько ситуаций, когда вы можете использовать метод async void — среда выполнения обнаружит его и отреагирует соответствующим образом. Но, как правило, лучше использовать async Task, если вам действительно необходимо сделать async void. - person Stephen Cleary; 13.08.2012
comment
поскольку async void по сути является огнем, и забудьте, что очень редко есть причина для этого. Одним из примеров является page_load в новых веб-формах - protected async void Page_Load (отправитель объекта, EventArgs e) - person Filip W; 14.08.2012

С возвращаемым типом void вы не ждете возврата объекта. Вы ждете завершения операции. Вы ждете завершения своей задачи.

person user1527329    schedule 11.08.2012
comment
Не уверен, на кого вы ссылаетесь, говоря, что вы (вы не ждете). Я не хочу ничего ждать. Дело в том, что он используется в WEB API, и я не могу понять, чего именно вы хотите, чтобы я ждал? - person user1561202; 11.08.2012

Если вы вернете void, вы немедленно вернете ответное сообщение 204 «Нет содержимого», независимо от статуса завершения вашей асинхронной операции. Это делается с помощью VoidResultConverter.

Примечание. В RC вы увидите, что он возвращает ответ 200 «ОК», но с RTM он возвращает ответ 204 «Нет содержимого».

person tugberk    schedule 11.08.2012