Async等待调用多个同步方法
本文关键字:同步方法 调用 等待 Async | 更新日期: 2023-09-27 18:03:53
我想知道如何最好地处理这个异步等待链,其中多个CPU绑定方法需要在异步链后依次调用。
我在下面输入了一个小例子。
我只是想找出性能最好/副作用最小的模式是什么。我要确保我没有破坏异步的好处。我的过滤器方法不访问任何异步和可等待的东西,所以要使它们异步意味着我必须在调用方法中返回Task.Run(() => Filter1(criterion)),或者类似await Task.Run(() =>{返回事件;});在过滤器方法本身中。如何获得最佳实践是一个问题。这是大多数讨论停止的地方,所以一个完整的例子和建议会很好。
有什么4.5异步等待大师可以给好的建议吗?
namespace test
{
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http;
public class sampleController : ApiController
{
private Service _service;
public sampleController()
{
_service = new Service();
}
public async Task<HttpResponseMessage> SomeTask(DiagnosesSearchCriterion criterion)
{
return Request.CreateResponse<IEnumerable<Diagnosis>>(HttpStatusCode.OK, await _service.GetDiagnosesByGroup(criterion));
}
}
public class Service
{
private Repository _repository;
public Service()
{
_repository = new Repository();
}
public async Task<IEnumerable<Diagnosis>> GetDiagnosis(DiagnosesSearchCriterion criterion)
{
System.IO.Stream events = await _repository.GetEvents(criterion);
// Will these block? Should they be async? They are CPU bound...
// how to best handle this, they need to be called sequentially in most cases.
events = Filter1(criterion, events);
events = Filter2(criterion, events);
return new Diagnosis[]{};
}
public System.IO.Stream Filter1(DiagnosesSearchCriterion criterion, System.IO.Stream events)
{
// CPU bound PLINQ and Parallel filtering logic here.....
return events;
}
public System.IO.Stream Filter2(DiagnosesSearchCriterion criterion, System.IO.Stream events)
{
// CPU bound PLINQ and Parallel filtering logic here.....
// ....
return events;
}
}
public class Repository
{
public async Task<System.IO.Stream> GetEvents(DiagnosesSearchCriterion criterion)
{
WebClient wc = new WebClient();
return await wc.OpenReadTaskAsync("http://www.blah.com/stuff");
}
}
}
在服务器端,async
的主要好处是可伸缩性—也就是说,如果请求只是等待一些I/O完成,则线程池线程从处理请求中解放出来。
在这种情况下(您的方法是cpu绑定的),将它们设置为async
没有任何好处。通过使用Task.Run
,您仍然会占用线程池线程(并增加少量开销)。因为它们应该按顺序执行,所以最简单的方法是同步调用它们,就像您的代码当前所做的那样。
我认为这种情况是解决在优秀的Async在ASP。网络视频。请注意,在客户端处理相同的情况会有所不同。在客户端,async
的主要好处是响应性,因此将CPU工作扔到线程池线程(Task.Run
)中是有意义的,因为这将释放UI线程。
(顺便说一下,在服务器上进行并行处理通常不是一个好主意,除非您确定您的用户数量非常低)。