简体   繁体   English

没有等待的尾调用异步

[英]Tail call async without await

Take this async method: 采用这种async方法:

public async Task<string> ReadStringFromUrlAsync(string url)
{
    WebRequest request = WebRequest.Create(url);
    WebResponse response = request.GetResponse();
    Stream dataStream = response.GetResponseStream();
    var reader = new StreamReader(dataStream);
    return await reader.ReadToEndAsync();
}

Because it returns the result of another task I believe I can do away with async and await : 因为它返回另一个任务的结果,我相信我可以取消asyncawait

public Task<string> ReadStringFromUrlAsync(string url)
{
    WebRequest request = WebRequest.Create(url);
    WebResponse response = request.GetResponse();
    Stream dataStream = response.GetResponseStream();
    var reader = new StreamReader(dataStream);
    return reader.ReadToEndAsync();
}

I noticed that the call stack in the event of an exception won't mention ReadStringFromUrlAsync , are there any other drawbacks to removing aysnc / await on tail calls in this way. 我注意到在异常事件中调用堆栈不会提到ReadStringFromUrlAsync ,以这种方式删除尾部调用上的aysnc / await是否有任何其他缺点。

It's fine in most cases, but there is an important difference in exception behavior: any exceptions before the task is returned will be thrown directly rather than placed on the task. 在大多数情况下都很好,但是异常行为有一个重要的区别:返回任务之前的任何异常都将直接抛出而不是放在任务上。 In your example, if WebRequest.Create , GetResponse , GetResponseStream , or StreamReader(..) throws, then in an async method that exception would be placed on the task, while in a non- async method that exception would be thrown directly. 在您的示例中,如果WebRequest.CreateGetResponseGetResponseStreamStreamReader(..)抛出,则在async方法中将异常放置在任务上,而在非async方法中则异常将直接抛出。

BTW, if that's representative of your real code, I'd recommend using HttpClient instead, which was designed with await in mind: 顺便说一句,如果这是代表你的真实代码,我推荐使用HttpClient替代,它在设计时await记:

public Task<string> ReadStringFromUrlAsync(string url)
{
  return new HttpClient().GetStringAsync(url);
}

You should be fine with removing this await and async . 删除这个awaitasync你应该没问题。 In fact, Roslyn (new C# Compiler) team is thinking about making it an compiler optimization . 实际上,Roslyn(新的C#编译器)团队正在考虑将其作为编译器优化

Yes, that is correct. 对,那是正确的。 When you're just returning a task, you can just omit the async and return the Task directly, without await ing. 当您刚刚返回任务时,您可以省略async并直接返回Task ,而无需await

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM