[英]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
: 因为它返回另一个任务的结果,我相信我可以取消async
并await
:
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.Create
, GetResponse
, GetResponseStream
或StreamReader(..)
抛出,则在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
. 删除这个await
和async
你应该没问题。 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.