何时使用"async"而不是返回新的Task.Run任务?

1 c# async-await .net-4.5

所以我在这里有一个功能

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

还有另一个功能

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

现在,我遇到了这种模式的一个相当不同的实现,你将把async关键字添加到一个返回的函数中Task<TResult>(这样它最终看起来像:) async Task<TResult> LoginAsync(SignupData sd).在这种情况下,即使您返回TResult而不是a Task<TResult>,程序仍然会编译.

我的问题是,哪个实施应该优先考虑?

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

还是这一个?

async static Task<bool> LoginAsync(SignupData sd)
{
    bool success=Login(sd);
    return success;
}
Run Code Online (Sandbox Code Playgroud)

小智 7

你不应该做任何一件事.如果异步方法可以阻止线程被阻塞,则它们非常有用.在您的情况下,您的方法不会避免这种情况,它总是阻塞一个线程.

如何处理长阻塞调用取决于应用程序.对于UI应用程序,您希望使用Task.Run以确保不阻止UI线程.对于如Web应用程序,你希望使用Task.Run,你只想用你得已防止两个线程正在使用的其中一个就足够的线程.

您的异步方法无法可靠地知道什么最适合调用方,因此不应通过其API指出它最了解.您应该只使用同步方法并让调用者决定.


也就是说,我建议寻找一种方法来创建一个LoginAsync非常异步的实现.例如,如果它从数据库加载数据,则使用打开连接,使用OpenAsync检索数据ExecuteReaderAsync.如果它连接到Web服务,请使用异步方法连接您正在使用的任何协议.如果在一些其他的方式登录,做任何你需要做的是异步的.

如果您采用这种方法,那么关键字asyncawait关键字非常有意义,并且可以使这种实现非常容易创建.