有时我需要启动一个工作非常缓慢的异步工作。我不在乎那份工作是否成功,我需要继续处理我当前的线程。
就像有时我需要发送一封电子邮件或短信,但工作速度很慢。我需要尽快回复网络客户端,所以我不想这样做await。
我用谷歌搜索了这个问题,有些文章建议我这样写:
// This method has to be async
public async Task<Response> SomeHTTPAction()
{
// Some logic...
// ...
// Send an Email but don't care if it successfully sent.
Task.Run(() => _emailService.SendEmailAsync());
return MyRespond();
}
Run Code Online (Sandbox Code Playgroud)
或者像这样:
// This method has to be async
public async Task<Response> SomeHTTPAction()
{
// Some logic...
// ...
// Send an Email but don't care if it successfully sent.
Task.Factory.StartNew(() => _emailService.SendEmailAsync());
return MyRespond();
}
Run Code Online (Sandbox Code Playgroud)
会有警告说: before the call is completed. Consider applying the 'await' operator to the result of the call.
那如果我真的await编辑了呢?在 C# 中“触发并忘记”的最佳实践是什么,只需调用异步方法而不等待其完成?
Cor*_*lis 20
如果你真的只想开火然后忘记。只是不要调用 use await。
// It is a good idea to add CancellationTokens
var asyncProcedure = SomeHTTPAction(cancellationToken).ConfigureAwait(false);
// Or If not simply do:
var asyncProcedure = SomeHTTPAction().ConfigureAwait(false);
Run Code Online (Sandbox Code Playgroud)
如果您想稍后使用结果输出,它会变得更加棘手。但如果它真的很火,忘记了上面的应该工作
取消令牌允许中断和取消过程。如果您正在使用 Cancellation 令牌,您将需要在从检索直接到调用方法的任何地方使用它(Turtles 一直向下)。
我以前是用来ConfigureAwait(false)防止死锁的。在这里了解更多信息
小智 12
单独丢弃是避免此警告的最佳方法。
_ = Task.Run(() => _emailService.SendEmailAsync());
Run Code Online (Sandbox Code Playgroud)
丢弃是虚拟变量,可用于忽略异步操作返回的 Task 对象。
https://docs.microsoft.com/en-us/dotnet/csharp/discards#a-standalone-discard
MrM*_*vin 10
如果您需要async在函数中使用,您还可以使用丢弃变量并且不要使用await。如果您有多个异步函数调用但不需要等待所有异步函数调用,这也很有用。
public async function(){
var tmp = await asyncfunction();
...
_ = _httpClient.PutAsync(url, content);
...
}
Run Code Online (Sandbox Code Playgroud)
正如Amadan在评论中所说,您需要从函数中删除 async。然后它会停止给你警告。
// This method has to be async
public Response SomeHTTPAction()
{
// Some logic...
// ...
// Send an Email but don't care if it successfully sent.
Task.Factory.StartNew(() => _emailService.SendEmailAsync());
return MyRespond();
}
Run Code Online (Sandbox Code Playgroud)
并且Task.Factory.StartNew(() => _emailService.SendEmailAsync());确实会在一个新线程上工作。
| 归档时间: |
|
| 查看次数: |
22597 次 |
| 最近记录: |