Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use Task.Factory.StartNew in MVC 4 async ApiController?

I'm using MVC4 ApiController to upload data to Azure Blob. Here is the sample code:

public Task PostAsync(int id)
{
    return Task.Factory.StartNew(() => 
    {
        // CloudBlob.UploadFromStream(stream);
    });
}

Does this code even make sense? I think ASP.NET is already processing the request in a worker thread, so running UploadFromStream in another thread doesn't seem to make sense since it now uses two threads to run this method (I assume the original worker thread is waiting for this UploadFromStream to finish?)

So my understanding is that async ApiController only makes sense if we are using some built-in async methods such as HttpClient.GetAsync or SqlCommand.ExecuteReaderAsync. Those methods probably use I/O Completion Ports internally so it can free up the thread while doing the actual work. So I should change the code to this?

public Task PostAsync(int id)
{
    // only to show it's using the proper async version of the method.
    return TaskFactory.FromAsync(BeginUploadFromStream, EndUploadFromStream...)
}

On the other hand, if all the work in the Post method is CPU/memory intensive, then the async version PostAsync will not help throughput of requests. It might be better to just use the regular "public void Post(int id)" method, right?

I know it's a lot questions. Hopefully it will clarify my understanding of async usage in the ASP.NET MVC. Thanks.

like image 851
Hengyi Avatar asked Nov 13 '22 11:11

Hengyi


1 Answers

Yes, most of what you say is correct. Even down to the details with completion ports and such.

Here is a tiny error:

I assume the original worker thread is waiting for this UploadFromStream to finish?

Only your task thread is running. You're using the async pipeline after all. It does not wait for the task to finish, it just hooks up a continuation. (Just like with HttpClient.GetAsync).

like image 180
usr Avatar answered Nov 15 '22 11:11

usr