考虑使用异步而不等待。
认为您可能误解了异步的作用。警告是 完全正确:如果您将方法标记为异步但不使用等待 任何地方,那么你的方法都不会是异步的。如果你调用它,所有 方法内的代码将同步执行。
我想编写一个应该异步运行但不需要使用await 的方法。例如,当使用线程时
public async Task PushCallAsync(CallNotificationInfo callNotificationInfo)
{
Logger.LogInfo("Pushing new call {0} with {1} id".Fill(callNotificationInfo.CallerId,
}
我想调用
PushCallAsync
并运行异步,并且不想使用等待。
我可以在 C# 中使用 async 而不使用 wait 吗?
你还是误会了
async
。 async
关键字确实not意味着“在另一个线程上运行”。
要将某些代码推送到另一个线程上,您需要显式地执行此操作,例如,
Task.Run
:
await Task.Run(() => Logger.LogInfo("Pushing new call {0} with {1} id".Fill(callNotificationInfo.CallerId));
async
/await
介绍文章,您可能会觉得有帮助。
如果您的
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));
}
你误会了
async
。
它实际上只是告诉编译器传播它在后台为您执行的控制流反转。这样整个方法堆栈就被标记为异步。
您实际想要做什么取决于您的问题。 (让我们考虑您的调用
Logger.LogInfo(..)
是一个 async
方法,因为它最终会调用 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);
}
public async Task PushCallAsync(CallNotificationInfo callNotificationInfo)
{
Logger.LogInfo("Pushing new call {0} with {1} id".Fill(callNotificationInfo.CallerId,
}
Logger.LogInfo
async
PushCallAsync
提供了await
的能力,但它从不等待任何东西
PushCallAsync
所暗示的那样),您必须找到同步调用
LogInfo
的替代方法。如果存在 LogInfoAsync
方法,尝试使用
await
来规避是不明智的。等待很重要,因为:
它捕获并抛出任务执行时可能发生的异常 - 否则这些异常将丢失/未处理LogInfoAsync()
,而无需等待结果。
由于您没有使用任何
await
,因此您不会标记该方法 async
。使它异步的不是
async
关键字,而是它异步调用其他方法。
public Task PushCallAsync(CallNotificationInfo callNotificationInfo)
{
// Fire and forget - we do not care about the result, failure, or order of this log message
_ = Logger.LogInfoAsync("Pushing new call {0} with {1} id".Fill(callNotificationInfo.CallerId,
Task.CompletedTask;
}
或非异步public void PushCall(CallNotificationInfo callNotificationInfo)
{
// Fire and forget - we do not care about the result, failure, or order of this log message
_ = Logger.LogInfoAsync("Pushing new call {0} with {1} id".Fill(callNotificationInfo.CallerId,
}
请注意,方法名称
Push暗示它是有序的。因此,如果您不关心顺序,我会以不同的方式命名它。否则,正如 Push 所暗示的那样,使用
await
来确保顺序是正确的。
ThreadPool.QueueUserWorkItem( foo => PushCallAsync(callNotificationInfo) );