如何将此同步方法调用链转换为异步(使用async / await运算符)?鉴于只有最后一次调用,DoRequest(),是一个需要时间执行的,是唯一需要变为异步的方法吗?或者链中的所有调用者,RequestSomething()和Process()是否也需要异步?
[HttpGet]
void Process()
{
var url = "http://someapi.com";
var myObject= RequestSomething(url);
//do something with the myObject.
}
MyObject RequestSomething(string url)
{
var request = new HttpRequestMessage(HttpMethod.Get, url);
var response = DoRequest(request);
return JsonConvert.DeserializeObject<MyObject>(response);
}
//method that takes time to return.
HttpResponseMessage DoRequest(HttpRequestMessage request)
{
var client = new HttpClient();
return client.SendAsync(request).Result;
}
答案 0 :(得分:4)
要正确地执行异步,它是&#34; infectious&#34;,如果您在一个位置执行此操作,则需要在调用链中一直执行此操作以获得任何真正的好处。因此,无论是调用Process()
还是需要处理从Process
返回的任务,要么等待它,要么像DoRequest
那样将链接传递给它。
async Task Process()
{
var url = "http://someapi.com";
var myObject= await RequestSomething(url);
//do something with the myObject.
}
async Task<MyObject> RequestSomething(string url)
{
var request = new HttpRequestMessage(HttpMethod.Get, url);
var response = await DoRequest(request).ConfigureAwait(false);
return JsonConvert.DeserializeObject<MyObject>(response);
}
//method that takes time to return.
Task<HttpResponseMessage> DoRequest(HttpRequestMessage request)
{
var client = new HttpClient();
return client.SendAsync(request);
}
因为您在执行请求后没有做任何额外的工作,所以在DoRequest
函数中不需要异步/等待,但其他的将需要async / await关键字。 .ConfigureAwait(false)
使得函数不必在UI线程上运行其余的代码,这可以为您带来小的性能提升。我不知道//do something with the myObject.
中的代码是否要求你在UI线程上,所以我没有把它放在等待,但如果你不需要在UI线程上你也可以在那里添加它。
答案 1 :(得分:1)
你应该做DoRequest ......
Public async Task<HttpResponseMessage> DoRequest(...
然后返回await client.SendAsync
同样,DoSomething应该是异步任务&lt; ...&gt;
您的调用方法,如果您想将其称为fire并忘记,则Process可以是async void,否则为异步任务。
答案 2 :(得分:-1)
尝试:
var task = Task.Run(() => RequestSomething());
var task2 = Task.Run(() => RequestSomethingElse());
await Task.WhenAll(task, task2);
如果您愿意,可以指定两个以上,或者只指定一个。