简体   繁体   中英

When to use “async” instead of returning a new Task.Run task?

So here I have a function

static bool Login(SignupData sd)
{
   bool success=false;
   /*
      Perform login-related actions here
   */
}

And there is another function

static Task<bool> LoginAsync(SignupData sd)
{
   return Task.Run<bool>(()=>Login(sd));
}

Now, I've come across a rather different implementation of this pattern, where you would add the async keyword to a function which returns Task<TResult> (so that it ends up looking like: async Task<TResult> LoginAsync(SignupData sd) ). In this case, even if you return TResult instead of a Task<TResult> , the program still compiles.

My question here is, which implementation should be prefered?

static Task<bool> LoginAsync(SignupData sd)
{
   return Task.Run<bool>(()=>Login(sd));
}

OR this one?

async static Task<bool> LoginAsync(SignupData sd)
{
    bool success=Login(sd);
    return success;
}

You shouldn't be doing either. Asynchronous methods are useful if they can prevent threads from being blocked. In your case, your method doesn't avoid that, it always blocks a thread.

How to handle long blocking calls depends on the application. For UI applications, you want to use Task.Run to make sure you don't block the UI thread. For eg web applications, you don't want to use Task.Run , you want to just use the thread you've got already to prevent two threads from being used where one suffices.

Your asynchronous method cannot reliably know what works best for the caller, so shouldn't indicate through its API that it knows best. You should just have your synchronous method and let the caller decide.


That said, I would recommend looking for a way to create a LoginAsync implementation that's really asynchronous. If it loads data from a database, for instance, open the connection using OpenAsync , retrieve data using ExecuteReaderAsync . If it connects to a web service, connect using the asynchronous methods for whatever protocol you're using. If it logs in some other way, do whatever you need to make that asynchronous.

If you're taking that approach, the async and await keywords make perfect sense and can make such an implementation very easy to create.

While HVD is correct, I will dive into async in an attempt to describe its intended use.

The async keyword, and the accompanying await keyword is a shortcut method of implementing non blocking code patterns within your application. While it plays along perfectly with the rest of the Task Parallel Library (TPL), it isn't usually used quite the same. It's beauty is in the elegance of how the compiler weaves in the asynchronicity, and allows it to be handled without explicitly spinning off separate threads, which may or may not be what you want.

For Example, let's look at some code:

async static Task<bool> DoStuffAsync()
{
    var otherAsyncResult = doOtherStuffAsync();

    return await otherAsyncResult
}

See the await keyword? It says, return to the caller, continue on until we have the result you need. Don't block, don't use a new thread, but basically return with a promise of a result when ready (A Task). The calling code can then carry on and not worry about the result until later when we have it.

Usually this ends up requiring that your code becomes non-blocking the whole way down (async all the way as it were), and often this is a difficult transition to understand. However, if you can it is incredibly powerful.

The better way to handle your code would be to make the synchronous code call the async one, and wait on it. That way you would be async as much as possible. It is always best to force that level as high as possible in your application, all the way to the UI if possible.

Hope that made sense. The TPL is a huge topic, and Async/Await really adds some interesting ways of structuring your code. https://msdn.microsoft.com/en-us/library/hh191443.aspx

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