在c#中将一系列同步方法转换为异步方法
本文关键字:转换 异步方法 同步方法 一系列 | 更新日期: 2023-09-27 18:15:23
如何将这条同步方法调用链转换为async(使用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;
}
要正确地执行异步,它是"具有传染性的",如果你在一个位置执行异步,你需要在调用链的所有位置执行异步,才能从中获得真正的好处。因此,无论调用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,但其他函数将需要async/await关键字。.ConfigureAwait(false)
使得函数不必在UI线程上运行它的其余代码,这可以给你一个小小的性能提升。我不知道//do something with the myObject.
中的代码是否需要你在UI线程上,所以我没有把它放在那个等待上,但是如果你不需要在UI线程上,你也可以把它添加到那里。
你应该让DoRequest…
Public async Task<HttpResponseMessage> DoRequest(...
然后返回等待客户端。
是以同样,DoSomething应该是async Task<…>
你的调用方法,Process可以是async void,如果你想调用它作为fire and forget,否则是一个async Task。
尝试:
var task = Task.Run(() => RequestSomething());
var task2 = Task.Run(() => RequestSomethingElse());
await Task.WhenAll(task, task2);
可以指定两个以上,也可以只指定一个。