简体   繁体   English

任务(异步,等待):我是否需要输入这些是所有连接层或只有ASYNC调用的那些,即HttpClient.GetAsync?

[英]Task(async, await): Do I need to enter these are all connecting layers or only ones with ASYNC calls i.e HttpClient.GetAsync?

I have come across a small issue, I have written a asp.net web api service and I automatically added "async" on the controller, of course this now requires that I use await. 我遇到了一个小问题,我编写了一个asp.net web api服务,我自动在控制器上添加了“async”,当然这要求我使用await。

The problem I have is that my controller is connected to a service layer and this service layer then connects to a data layer - this data layer is the layer that is calling an ASYNC version of GET to make an asynchronous call to another REST service - so this is easy, I can convert my data layer method to have an "async" keyword and i will place a await on the HttpClient GetSync call. 我遇到的问题是我的控制器连接到服务层,然后这个服务层连接到数据层 - 这个数据层是调用ASYNC版本的GET以对另一个REST服务进行异步调用的层 - 所以这很容易,我可以将数据层方法转换为具有“ async”关键字,并且将在HttpClient GetSync调用上进行等待。

but my service layer to support async / await I need to change the return type to Task but the service layer really isn't doing anything ASYNC its calling to the data layer that is actually calling HttpClient async methods. 但是我的服务层支持async / await我需要将返回类型更改为Task但是服务层实际上没有做任何ASYNC调用它实际调用HttpClient异步方法的数据层。

So I have 2 options considering I have the following layer structure. 考虑到我有以下层结构,我有2个选项。

ASP.NET Web Api >> Service Layer >> Data Layer ASP.NET Web Api >>服务层>>数据层

Only have async and await used in the Data Layer and be done with it. 仅在数据层中使用异步并等待,然后完成它。

Or place async and await on the controller and the method from the service layer, this requires refactoring as I need to return Task. 或将异步并从服务层放在控制器和方法上,这需要重构,因为我需要返回Task。

I suppose where I am not understanding it fully, technically the only blocking calls would be in the data layer, so to have all threads returned the thread pool for use I should only be concerned with placing async and await on the data layer ? 我想我完全不了解它,从技术上讲,唯一的阻塞调用将在数据层中,所以要让所有线程返回线程池以供使用我应该只关心在数据层上放置async和await?

When would i need to use pattern on the controllers ??? 我何时需要在控制器上使用模式???

Look forward to any help 期待任何帮助

I automatically added "async" on the controller, of course this now requires that I use await. 我在控制器上自动添加了“async”,当然这要求我使用await。

That is backwards. 那是倒退。 You should only add async to a method if you need to use await . 如果需要使用await则只应向方法添加async

Only have async and await used in the Data Layer and be done with it. 仅在数据层中使用异步并等待,然后完成它。

You shouldn't wrap asynchronous methods within synchronous APIs . 您不应该在同步API中包装异步方法 This is especially true in server code, because then you lose all the benefits of async . 在服务器代码中尤其如此,因为这会失去async所有好处。

Or place async and await on the controller and the method from the service layer, this requires refactoring as I need to return Task. 或将异步并从服务层放在控制器和方法上,这需要重构,因为我需要返回Task。

This is the correct approach. 这是正确的方法。 Follow these guidelines: 请遵循以下准则:

  1. Do not block on async code. 不要阻止async代码。 Eg, do not call Task.Wait or Task<T>.Result . 例如,不要调用Task.WaitTask<T>.Result I describe on my blog how this can cause deadlocks , but even if you hack it to work reliably, you'll still lose all the benefits of async on the server side. 我在博客中描述了这会导致死锁 ,但即使你破解它可靠地工作,你仍然会失去服务器端async所有好处。
  2. Avoid async void . 避免async void Especially on the server side. 特别是在服务器端。
  3. Instead of Wait or Result , use await . 而不是WaitResult ,使用await This means that the awaiting method will have to be async Task or async Task<T> , which means that methods that call the awaiting method will also have to await. 这意味着等待方法将必须是async Taskasync Task<T> ,这意味着调用等待方法的方法也必须等待。 So async will "grow" through your code. 所以async将通过你的代码“增长”。 This is normal and correct. 这是正常和正确的。

You may find my article on Best Practices in Asynchronous Programming helpful. 您可能会发现有关异步编程最佳实践的文章很有帮助。

If your calling thread has nothing meaningful to do then there is no benefit in creating a separate task that will do the work for you. 如果您的调用线程没有任何意义,那么创建一个可以为您完成工作的单独任务没有任何好处。

However if the calling thread has other things to do, for instance keep the UI responsive, then the calling thread might want to call your function in a separate task, do the other things and when it needs the result await for the result. 但是,如果调用线程有其他事情要做,例如保持UI响应,则调用线程可能希望在单独的任务中调用您的函数,执行其他操作以及何时需要结果等待结果。

Example: 例:

private async YourAsyncWebFunction(...)
{
    // do some processing
    // call other async functions ans wait for it to finish:
    await OtherAsync(...);
    var result = await OtherAsync2(...)
    if (result == ...) { ... }
}

private void MyMainFunction(...)
{
    var taskWebFunction = Task.Run( () => YourAsyncWebFunction(...));
    // do other things
    // after a while: you need the task to finish:
    await taskWebFunction;
    // do other things
 }

If your main function is an event handler you don't have to do Task.Run, just declare the event handler async 如果你的main函数是一个事件处理程序,你不必执行Task.Run,​​只需声明事件处理程序async

The event handler is the only async function that may return void Instead of Task or Task <TResult > 事件处理程序是唯一可能返回void的异步函数,而不是Task或Task <TResult >

private async void OnButton1_Clicked(object sender, ...)
{
     // do some processing
     await YourAsyncWebFunction(...)
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM