在有关eliding async await的文章中,有一个如下示例:
public Task<string> GetElidingKeywordsAsync(string url)
{
using (var client = new HttpClient())
return client.GetStringAsync(url);
}
他对流程的描述如下:
使用GetElidingKeywordsAsync,代码可以执行以下操作:
创建HttpClient对象。
调用GetStringAsync,它返回一个 任务不完整。
处理HttpClient对象。
返回从GetStringAsync返回的任务。
为什么流程不如下?
创建HttpClient对象。
处理HttpClient对象。
调用GetStringAsync,并返回从GetStringAsync返回的任务。
答案 0 :(得分:4)
没有花括号或分号的using块具有隐含的主体:
public Task<string> GetElidingKeywordsAsync(string url)
{
using (var client = new HttpClient())
return client.GetStringAsync(url); // using body
}
这可以归一化为:
public Task<string> GetElidingKeywordsAsync(string url)
{
using (var client = new HttpClient())
{
return client.GetStringAsync(url);
}
}
或更紧凑地用C#8.0编写:
public Task<string> GetElidingKeywordsAsync(string url)
{
using var client = new HttpClient();
return client.GetStringAsync(url);
}
如果添加分号,则将出现一个空的主体,并产生您在OP中描述的行为:
public Task<string> GetElidingKeywordsAsync(string url)
{
HttpClient client;
using (client = new HttpClient()); // gets disposed before next statement
return client.GetStringAsync(url); // don't be fooled by the indent
}
这可以归一化为:
public Task<string> GetElidingKeywordsAsync(string url)
{
HttpClient client;
using (client = new HttpClient())
{
}
return client.GetStringAsync(url);
}
答案 1 :(得分:2)
扩展上面给出的注释,如果您了解GetStringAsync
方法的工作原理,将会很有帮助。
假设以下是aysnc方法:
public async Task<string> GetMethodAsync(string url)
{
// perform some operations
// execution will pause here due to await statement
// after calling download URL and the Task will be returned
var result = await DownloadURL(string);
//perform some more function
// finally return the result
return result;
}
请注意,此处将执行对DownloadURL
的方法调用,然后只有执行暂停以等待结果返回,然后返回task
。制作方法Async本身并不能使您延迟执行,而仅在await调用之后的部分得到“延迟”。
这就是为什么您将获得不完整的任务,然后在下一步处理客户的原因。