C# 使用“Task.Run”或不使用“await”调用异步方法,触发并忘记`
注意:这是一个不属于Asp.Net和web应用领域的问题 一般来说,尤其是当涉及到库或控制台应用程序时,为了启动并忘记异步方法,是否最好只调用异步方法而不等待它或使用任务运行 基本上:C# 使用“Task.Run”或不使用“await”调用异步方法,触发并忘记`,c#,C#,注意:这是一个不属于Asp.Net和web应用领域的问题 一般来说,尤其是当涉及到库或控制台应用程序时,为了启动并忘记异步方法,是否最好只调用异步方法而不等待它或使用任务运行 基本上: public static void Main(){ // Doing _ = DoSomethingAsync(); // vs. _ = Task.Run(DoSomethingAsync); } private static async Task DoSomethingAsync()
public static void Main(){
// Doing
_ = DoSomethingAsync();
// vs.
_ = Task.Run(DoSomethingAsync);
}
private static async Task DoSomethingAsync()
{
...
}
一般来说,这取决于任务。运行是更安全的选择,它背后的推理取决于两件事:
async
方法总是异步的。对于库项目或异步方法位于调用方不管理的代码中,保证方法始终是异步的可能变得特别棘手。例如,一旦我在库中实现了类似于此示例的方法:onmessagentification
同步操作,并且必须等待DoSlowOperation()
完成。因此,为了避免修复问题,我不得不将其更改为:
_ = Task.Run(onMessageNotification);
_ = MakePizzaAsync();
wait
操作之前,异步方法中不会有长时间运行的操作。调用者可能导致问题的另一种方式是,如果onMsgnotification
Func是通过以下方式实现的:Func onMsgNotification=async()=>{
DoSlowOperation();
等待异步操作();
}
这仍然会减慢HandleMessages
方法的速度,因为DoSlowOperation
仍在同步调用
一般来说,尤其是当涉及到库或控制台应用程序时,为了触发并忘记异步方法,最好是在不等待异步方法的情况下调用它,或者使用Task.Run
一般来说,最好不要用火,不要忘记
“开火并忘记”是指:
任务。考虑将<代码>任务<代码>添加到您的返回类型中,或者将其作为属性公开。
特别是在图书馆里,采用“火与忘”意味着你迫使所有的消费者永远不知道什么时候关闭和退出是安全的。但是,如果你真的想做的火和忘记,有几个选择
A.一个选项是调用异步void
函数。消费应用程序仍然无法确定代码是否/何时完成,但至少在这种情况下不会忽略异常
B.另一种选择是在没有上下文的情况下启动任务。此选项具有激发和忘记代码的两个缺点:异常被忽略,调用代码无法知道何时完成
这两个建议都是在没有上下文的情况下启动任务的。有,或者您可以在任务中包装调用。运行(效率稍低,但工作正常)
我不建议直接开始这项任务。虽然这在控制台应用程序中可以正常工作,但它不适合在提供上下文的情况下调用库
Func<Task> onMsgNotification = () => {
DoSlowOperation();
return Task.CompletedTask;
}
_ = Task.Run(onMessageNotification);
_ = MakePizzaAsync();
Func<Task> onMsgNotification = async () => {
DoSlowOperation();
await AsyncOperation();
}