Search code examples
c#asp.net-mvc-4asp.net-web-apiasync-awaitasync-ctp

Returning Void in Async method from WEB API Controller


I have this async method inside ASP.NET MVC 4 WEB API Controller that I got from this blog: http://www.strathweb.com/2012/04/html5-drag-and-drop-asynchronous-multi-file-upload-with-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;
    }

My question is why exactly does this method have a return type of Task? It is not clear "where to" or "to whom" it returns this task? It's like there is no one that waits for/receives the returned object.

I wonder what will be the implications if I return void like this:

EDIT:

I have tried the code below and it completely breaks the program. it's like the runtime looses the reference to the code, the code itself doesn't finish running.

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

    }

Solution

  • The ASP.NET runtime waits for it. You may find this video useful.

    Most examples for async assume a UI context. ASP.NET also provides a context, but it's a "request" context - one for each HTTP request. My async/await post gives an overview of this "context", and the async/await FAQ goes into much more detail.