34

考虑使用 async 而不使用 await

认为您可能误解了 async 的作用。警告是完全正确的:如果您将方法标记为异步但不在任何地方使用 await,那么您的方法将不是异步的。如果调用它,方法内的所有代码都会同步执行。

我想编写一个应该运行异步但不需要使用等待的方法。例如在使用线程时

public async Task PushCallAsync(CallNotificationInfo callNotificationInfo)
{
    Logger.LogInfo("Pushing new call {0} with {1} id".Fill(callNotificationInfo.CallerId,
}

我想调用PushCallAsync并运行异步并且不想使用等待。

我可以在 C# 中使用 async 而不等待吗?

4

4 回答 4

34

如果您Logger.LogInfo已经是异步的,这就足够了:

public void PushCallAsync(CallNotificationInfo callNotificationInfo)
{
    Logger.LogInfo("Pushing new call {0} with {1} id".Fill(callNotificationInfo.CallerId,
}

如果它不只是异步启动它而不等待它

public void PushCallAsync(CallNotificationInfo callNotificationInfo)
{
    Task.Run(() => Logger.LogInfo("Pushing new call {0} with {1} id".Fill(callNotificationInfo.CallerId));
}
于 2013-07-23T09:11:57.997 回答
33

你还是误会了async。该async关键字并不意味着“在另一个线程上运行”。

要将一些代码推送到另一个线程,您需要明确地执行此操作,例如Task.Run

await Task.Run(() => Logger.LogInfo("Pushing new call {0} with {1} id".Fill(callNotificationInfo.CallerId));

我有一个async/await介绍帖子,您可能会觉得有帮助。

于 2013-07-23T10:22:50.643 回答
6

你误会了async。它实际上只是告诉编译器传播它在后台为您执行的控制流的反转。这样整个方法堆栈就被标记为异步。

你真正想要做什么取决于你的问题。(让我们认为您的调用Logger.LogInfo(..)是一种async方法,因为它最终会调用 File.WriteAsync() 左右。

  • 如果你调用函数是一个 void 事件处理程序,你很好。异步调用将在一定程度上(即 File.WriteAsync)在后台发生。您不希望在您的控制流中有任何结果。那就是火,然后忘记。
  • 但是,如果您想对结果做任何事情,或者如果您只想在那个时候继续,当Logger.LogInfo(..)完成时,您必须采取预防措施。当您的方法以某种方式位于调用堆栈的中间时,就是这种情况。然后Logger.LogInfo(..)通常会返回一个Task并且您可以等待。但要小心调用 task.Wait() 因为它会死锁你的 GUI 线程。而是使用等待或返回任务(然后您可以省略异步):

public void PushCallAsync(CallNotificationInfo callNotificationInfo) 
{
   return Logger.LogInfo("Pushing new call {0} with {1} id".Fill(callNotificationInfo.CallerId); 
}

或者

 public async void PushCallAsync(CallNotificationInfo callNotificationInfo) 
 {
    await Logger.LogInfo("Pushing new call {0} with {1} id".Fill(callNotificationInfo.CallerId); 
 }
于 2016-01-07T08:16:26.353 回答
2

如果 Logger.LogInfo 是一个同步方法,那么整个调用无论如何都是同步的。如果您只想在单独的线程中执行代码,那么异步不是这项工作的工具。尝试使用线程池:

ThreadPool.QueueUserWorkItem( foo => PushCallAsync(callNotificationInfo) );
于 2013-07-23T09:21:04.427 回答