Ben*_*ron 43 .net c# asp.net-web-api asp.net-core
我有一个.net核心API,它有一个控制器,用于构建要返回的聚合对象.它创建的对象由来自对服务类的3个方法调用的数据组成.它们彼此独立,可以彼此隔离运行.目前我正在使用任务来提高此控制器的性能.当前版本看起来像这样......
[HttpGet]
public IActionResult myControllerAction()
{
var data1 = new sometype1();
var data2 = new sometype2();
var data3 = new List<sometype3>();
var t1 = new Task(() => { data1 = service.getdata1(); });
t1.Start();
var t2 = new Task(() => { data2 = service.getdata2(); });
t2.Start();
var t3 = new Task(() => { data3 = service.getdata2(); });
t3.Start();
Task.WaitAll(t1, t2, t3);
var data = new returnObject
{
d1 = data1,
d2 = data2,
d2 = data3
};
return Ok(data);
}
Run Code Online (Sandbox Code Playgroud)
这很好用,但我想知道在这里使用任务是否是最佳解决方案?使用async/await是一个更好的主意和更容易接受的方式吗?
例如,控制器是否应标记为异步,并且每次调用服务方法时都要等待?
Ste*_*ary 65
这很好用,但我想知道在这里使用任务是否是最佳解决方案?使用async/await是一个更好的主意和更容易接受的方式吗?
是的,一点没错.在ASP.NET上执行并行处理会占用每个请求多个线程,这会严重影响您的可伸缩性.异步处理在I/O方面要优越得多.
要使用async
,首先从您的最低级别电话开始,在服务中的某个地方.它可能在某个时候进行HTTP调用; 改变它以使用异步HTTP调用(例如,HttpClient
).然后让async
自然从那里成长.
最终,您将最终得到异步getdata1Async
,getdata2Async
和getdata3Async
方法,这些方法可以同时使用:
[HttpGet]
public async Task<IActionResult> myControllerAction()
{
var t1 = service.getdata1Async();
var t2 = service.getdata2Async();
var t3 = service.getdata3Async();
await Task.WhenAll(t1, t2, t3);
var data = new returnObject
{
d1 = await t1,
d2 = await t2,
d3 = await t3
};
return Ok(data);
}
Run Code Online (Sandbox Code Playgroud)
使用此方法,在三个服务调用正在进行时,myControllerAction
使用零线程而不是四个.
Ser*_*kiy 12
[HttpGet]
public async Task<IActionResult> GetAsync()
{
var t1 = Task.Run(() => service.getdata1());
var t2 = Task.Run(() => service.getdata2());
var t3 = Task.Run(() => service.getdata3());
await Task.WhenAll(t1, t2, t3);
var data = new returnObject
{
d1 = t1.Status == TaskStatus.RanToCompletion ? t1.Result : null,
d2 = t2.Status == TaskStatus.RanToCompletion ? t2.Result : null,
d3 = t3.Status == TaskStatus.RanToCompletion ? t3.Result : null
};
return Ok(data);
}
Run Code Online (Sandbox Code Playgroud)
TaskWhenAll
返回awaitable任务对象.因此,使用异步方法,您可以等待任务而不是阻塞线程.Task<T>
返回所需类型的结果,而不是创建局部变量并在任务中分配它们.Task<TResult>.Run
方法而不是创建和运行任务Get
null
,如果某些任务未成功完成,我会使用返回对象属性的值.您可以使用其他方法 - 例如,如果某些任务失败,则返回错误. 归档时间: |
|
查看次数: |
59982 次 |
最近记录: |