如何在asp.net中进行异步Web调用

Luk*_*Feo 0 c# asp.net wcf asynchronous async-await

让我们说在一个ASP.NET应用程序,WCF或Web API中,这个应用程序工作的一部分是在途中联系第三方.我喜欢异步或非阻塞地执行此操作,以便线程池不会饿死.但是,我不想在服务中更改我的所有代码,只需要进行Web调用.

这是我写的一些代码:

    public string GetSomeData()
    {
        Task<string> stuff = CallApiAsync(); 

        return stuff.result; //does this block here?

    }

    private async Task<string> CallApiasync()
    {
        using (var httpClient = new HttpClient())
        {
            string response = await httpClient.GetStringAsync(Util.EndPoint).ConfigureAwait(false); 

            return response;
        }

    }
Run Code Online (Sandbox Code Playgroud)

我认为这个想法如下,但请纠正任何误解.

CallApi的调用者可以调用该方法,当它等待等待时,会创建一个Task,它代表一些异步完成的工作,但这需要一些时间.此时线程到达等待返回到线程池以执行其他操作,即处理不同的请求.一旦任务完成,await线就会唤醒并且代码从那里继续,就好像它是同步的一样.

如果是这种情况,为什么我需要从我的apimethod返回一个任务.调用者似乎必须调用stuff.Result,这意味着任务可能没有完成,调用结果可能会阻塞?注意我不想让调用方法异步,因为调用它的方法需要是异步等等.

我的代码中的事件顺序是什么?

另一个问题是为什么我需要将configureAwait设置为false?否则一切都会挂起.

Ste*_*ary 6

我喜欢异步或非阻塞地执行此操作,以便线程池不会饿死.但是,我不想在服务中更改我的所有代码,只需要进行Web调用.

那是不可能的.为了真正异步,您必须允许async在代码中"增长"它所需的范围.你要做的是阻止异步调用,这不会给你任何好处(你通过使用释放一个线程async,但是你通过使用转而使用线程Result).

此时线程到达等待返回到线程池以执行其他操作,即处理不同的请求.

不完全的.当async方法命中时await,它Task 会向其调用者返回不完整的内容.如果主叫方,反过来,awaits表示任务,那么返回一个不完整的Task,以当ASP.NET运行时接收到一个不完整的调用者等Task从你的动作/服务法/不管,那么它会释放线程的线程池.

所以,你必须" async一路走"才能看到真正的好处async.

我有一个async介绍,如果你想要一个更温和的介绍,以及对一个MSDN文章在我的博客async的最佳实践(:其中之一是async所有的方式).我还有一篇博客文章描述了你所看到僵局.