简体   繁体   中英

nested async methods and thread pool Asp.Net

I'm building an async Web Api and after reading some articles about async / await I think I'm doing something wrong.

this is my actual code:

public async Task<IHttpActionResult> GetAccount(int id)
{
    var i = await GetInstanceIdAsync(User, _db); //grabs a thread
    ...
}

public async static Task<int> GetInstanceIdAsync(IPrincipal user, Entities db)
{
    var userManager = 
         new UserManager<ControliUser>(new UserStore<ControliUser>(db));
    //next line grabs another thread but since it was called from an await
    //it holds 2 threads, am I correct?
    var u = await userManager.FindByNameAsync(user.Identity.Name);
    return u == null ? 0 : u.InstanceId ?? 0;
}

So my first question is, Is this consuming 2 threads?

If the answer is yes, then I made this extension method to prevent that.

public static Task<int?> InstanceIdAsync(this Entities db, IPrincipal user)
{
    var userManager = new UserManager<ControliUser>(new UserStore<ControliUser>(db));
    return userManager.FindByNameAsync(user.Identity.Name).ContinueWith(t =>
    {
        if (t.IsCompleted && t.Result != null)
            return t.Result.InstanceId;
        return null;
    });
}

I think this method will only consume 1 thread and reduce overhead since it saves an async method

Am I correct?

So my first question is, Is this consuming 2 threads?

No. Using async-await doesn't generate any extra thread use. On the contrary, it frees the thread while the async operation is ongoing. This means that the thread will be used until the call to FindByNameAsync , then it will be freed, only to resume once that operation is complete. Then, it will resume the operation (code after the first await ) on an arbitrary thread-pool thread, while preserving the request context.

I think this method will only consume 1 thread and reduce overhead since it saves an async method

First of all, this won't work in WebAPI. The problem is that the continuation will only execute once the first task completes. This in turn, will signal the synchronization context that there are on-finished IO operations on-going, and will cause an exception.

As previously said, the async method doesn't generate any thread-use, all it does is create a state-machine so it can invoke the continuation of your method (any calls after the first await ) properly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM