C# Task(async,await):我需要输入这些都是连接层,还是只需要输入带有异步调用的层,即HttpClient.GetAsync?

C# Task(async,await):我需要输入这些都是连接层,还是只需要输入带有异步调用的层,即HttpClient.GetAsync?,c#,.net,task-parallel-library,async-await,C#,.net,Task Parallel Library,Async Await,我遇到了一个小问题,我编写了一个asp.NETWebAPI服务,并在控制器上自动添加了“async”,当然这现在需要我使用Wait 我的问题是,我的控制器连接到一个服务层,然后这个服务层连接到一个数据层-这个数据层是调用异步版本的GET以对另一个REST服务进行异步调用的层-因此这很容易,我可以将我的数据层方法转换为“异步”关键字,我将在HttpClient GetSync调用上放置一个wait 但是我的服务层要支持async/await,我需要将返回类型更改为Task,但是服务层实际上没有做任

我遇到了一个小问题,我编写了一个asp.NETWebAPI服务,并在控制器上自动添加了“async”,当然这现在需要我使用Wait

我的问题是,我的控制器连接到一个服务层,然后这个服务层连接到一个数据层-这个数据层是调用异步版本的GET以对另一个REST服务进行异步调用的层-因此这很容易,我可以将我的数据层方法转换为“异步”关键字,我将在HttpClient GetSync调用上放置一个wait

但是我的服务层要支持async/await,我需要将返回类型更改为Task,但是服务层实际上没有做任何异步操作,它调用的数据层实际上正在调用HttpClient异步方法

考虑到下面的层结构,我有两个选择

ASP.NET Web Api>>服务层>>数据层

仅在数据层中使用async和await,然后使用它

或者将async和wait放在服务层的控制器和方法上,这需要重构,因为我需要返回任务

我想在我没有完全理解它的地方,技术上唯一的阻塞调用将在数据层中,所以要让所有线程返回线程池以供使用,我应该只关心在数据层上放置async和Wait

我什么时候需要在控制器上使用模式

期待任何帮助

我在控制器上自动添加了“async”,当然现在需要使用wait

这是倒退。如果需要使用
wait
,则只应向方法添加
async

仅在数据层中使用async和await,然后使用它

。在服务器代码中尤其如此,因为这样您就失去了
async
的所有好处

或者将async和wait放在服务层的控制器和方法上,这需要重构,因为我需要返回任务

这是正确的做法。遵循以下准则:

  • 不要阻塞
    async
    代码。例如,不要调用
    Task.Wait
    Task.Result
    。我在我的博客上描述了这一点,但即使你将其修改为可靠工作,你仍然会失去服务器端
    async
    的所有好处
  • 避免
    异步无效
    。特别是在服务器端
  • 使用
    Wait
    代替
    Wait
    Result
    。这意味着等待方法必须是
    async Task
    async Task
    ,这意味着调用等待方法的方法也必须等待。因此
    async
    将通过您的代码“增长”。这是正常和正确的

  • 您可能会发现我关于的文章很有帮助。

    如果您的调用线程没有什么有意义的事情要做,那么创建一个单独的任务来为您完成工作是没有好处的

    但是,如果调用线程还有其他事情要做,例如保持UI响应,那么调用线程可能希望在单独的任务中调用您的函数,执行其他事情,并在需要结果时等待结果

    例如:

    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
     }
    
    如果主函数是事件处理程序,则不必执行Task.Run,只需将事件处理程序声明为异步

    事件处理程序是唯一可以返回void而不是Task或Task


    谢谢Stephen的回复,是的,我理解没有在任何异步ie上阻塞。没有使用Result。。。。我想您已经回答了我的问题,所以我将重构所有调用我的数据层的方法,以使用Task和async以及wait。这正是我所关心的,我希望得到一些澄清。实际上,我只是想,如果我只是让数据层异步,让wait感知,而不做其他事情,那么线程可以从技术上跳出(它会这样做),并在wait方法返回之前从技术上完成程序流,因此,我的控制器将在产生结果之前完成-这是正确的吗马丁:如果你想那样做,你会发现那是不可能的;您必须使用类似于
    等待
    结果
    ,这会阻止请求线程。是的。。。伟大的好的,我正在添加async并等待我链中的所有方法。。。谢谢你的帮助
    private async void OnButton1_Clicked(object sender, ...)
    {
         // do some processing
         await YourAsyncWebFunction(...)
    }