在 C# 中使用异步而不等待?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17805887/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using async without await in C#?
提问by
Consider Using async without await.
think that maybe you misunderstand what async does. The warning is exactly right: if you mark your method async but don't use await anywhere, then your method won't be asynchronous. If you call it, all the code inside the method will execute synchronously.
认为您可能误解了 async 的作用。警告是完全正确的:如果您将方法标记为异步但不在任何地方使用 await,那么您的方法将不会是异步的。如果调用它,该方法内的所有代码都会同步执行。
I want write a method that should run async but don't need use await.for example when use a thread
我想写一个应该异步运行但不需要使用等待的方法。例如,当使用线程时
public async Task PushCallAsync(CallNotificationInfo callNotificationInfo)
{
Logger.LogInfo("Pushing new call {0} with {1} id".Fill(callNotificationInfo.CallerId,
}
I want call PushCallAsyncand run async and don't want use await.
我想调用PushCallAsync并运行异步,不想使用等待。
Can I use async without await in C#?
我可以在 C# 中使用 async 而没有 await 吗?
回答by Visions
If your Logger.LogInfois already async this is enough:
如果您Logger.LogInfo已经是异步的,这就足够了:
public void PushCallAsync(CallNotificationInfo callNotificationInfo)
{
Logger.LogInfo("Pushing new call {0} with {1} id".Fill(callNotificationInfo.CallerId,
}
If it is not just start it async without waiting for it
如果它不只是异步启动它而不等待它
public void PushCallAsync(CallNotificationInfo callNotificationInfo)
{
Task.Run(() => Logger.LogInfo("Pushing new call {0} with {1} id".Fill(callNotificationInfo.CallerId));
}
回答by ya23
If Logger.LogInfo is a synchronous method, the whole call will be synchronous anyway. If all you want to do is to execute the code in a separate thread, async is not the tool for the job. Try with thread pool instead:
如果 Logger.LogInfo 是同步方法,则整个调用无论如何都是同步的。如果您只想在单独的线程中执行代码,则 async 不是该工作的工具。尝试使用线程池:
ThreadPool.QueueUserWorkItem( foo => PushCallAsync(callNotificationInfo) );
回答by Stephen Cleary
You still are misunderstanding async. The asynckeyword does notmean "run on another thread".
你还是误会了async。该async关键字并不会意味着“另一个线程上运行”。
To push some code onto another thread, you need to do it explicitly, e.g., Task.Run:
要将一些代码推送到另一个线程,您需要明确地执行此操作,例如Task.Run:
await Task.Run(() => Logger.LogInfo("Pushing new call {0} with {1} id".Fill(callNotificationInfo.CallerId));
I have an async/awaitintro postthat you may find helpful.
我有一篇async/await介绍文章,您可能会觉得有帮助。
回答by Robetto
You're misunderstanding async.
It actually just tells the Compiler to propagate the inversion of control flow it does in the background for you. So that the whole method stack is marked as async.
你误会了async。它实际上只是告诉编译器传播它在后台为您所做的控制流的反转。以便将整个方法堆栈标记为异步。
What you actually want to do depends on your problem. (Let's consider your call Logger.LogInfo(..)is an asyncmethod as it does eventually call File.WriteAsync() or so.
你真正想要做什么取决于你的问题。(让我们考虑您的调用Logger.LogInfo(..)是一种async方法,因为它最终会调用 File.WriteAsync() 左右。
- If you calling function is a void event handler, you're good. The async call will happen to some degree (namely File.WriteAsync) in the background. You do not expect any result in your control flow. That is fire and forget.
- If however you want to do anything with the result or if you want to continue only then, when
Logger.LogInfo(..)is done, you have to do precautions. This is the case when your method is somehow in the middle ofthe call-stack. ThenLogger.LogInfo(..)will usually return aTaskand that you can wait on. But beware of calling task.Wait() because it will dead lock your GUI-Thread. Instead use await or return the Task (then you can omit async):
- 如果您调用的函数是一个 void 事件处理程序,那就很好了。异步调用会在后台发生某种程度的(即 File.WriteAsync)。您不希望在您的控制流中产生任何结果。那就是火与遗忘。
- 然而,如果你想对结果做任何事情,或者如果你只想继续,当
Logger.LogInfo(..)完成时,你必须采取预防措施。当您的方法以某种方式位于调用堆栈的中间时,就是这种情况。然后Logger.LogInfo(..)通常会返回一个Task,你可以等待。但要小心调用 task.Wait() 因为它会死锁你的 GUI 线程。而是使用 await 或返回任务(然后您可以省略异步):
public void PushCallAsync(CallNotificationInfo callNotificationInfo)
{
return Logger.LogInfo("Pushing new call {0} with {1} id".Fill(callNotificationInfo.CallerId);
}or
或者
public async void PushCallAsync(CallNotificationInfo callNotificationInfo)
{
await Logger.LogInfo("Pushing new call {0} with {1} id".Fill(callNotificationInfo.CallerId);
}

