什么是“正确方法"?同步使用HttpClient? [英] What's the "right way" to use HttpClient synchronously?

查看:101
本文介绍了什么是“正确方法"?同步使用HttpClient?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在正确的方法"周围使用了引号,因为我已经清楚地知道使用异步API的正确方法是简单地使异步行为传播到整个调用链中.这不是一个选择.

I used quote marks around "right way" because I'm already well aware that the right way to use an asynchronous API is to simply let the asynchronous behavior propagate throughout the entire call chain. That's not an option here.

我正在处理一个非常大而复杂的系统,该系统专门设计用于在循环中同步进行批处理.

I'm dealing with a very large and complicated system designed specifically to do batch processing synchronously in a loop.

我突然使用HttpClient的原因是因为在此之前,用于批处理的所有数据都是从SQL数据库中收集的,现在我们将Web API调用添加到混合中.

The reason why suddenly I'm using HttpClient is because prior to now all data for the batch processing was gathered from a SQL database, and now we're adding a Web API call to the mix.

是的,我们正在同步执行循环中调用Web API.我知道.重写整个事情是异步的不是一个选择.这实际上是我们想要做的. (我们正在尽可能减少API调用的次数)

Yes, we're calling a Web API in a synchronously executing loop. I know. Rewriting the whole thing to be async just isn't an option. This is actually what we want to do. (We're minimizing the number of API calls as much as possible)

我实际上 did 试图在调用链上传播异步行为,但是后来我发现自己有50个文件有很深的变化,仍然有数百个编译器错误需要解决,并失去了所有希望.我被击败了.

I actually did try to propagate the async behavior up the call chain, but then I found myself 50 files deep in changes, still with hundreds of compiler errors to resolve, and lost all hope. I am defeated.

然后,回到问题所在,考虑到微软的建议,从不使用WebRequest进行新开发,而改用HttpClient,后者仅提供异步API,我该怎么办?

So then, back to the question, given Microsoft's recommendation to never use WebRequest for new development and to instead use HttpClient, which offers only an asynchronous API, what am I to do?

这是我在做什么的伪代码...

Here is some pseudo-code of what I'm doing...

foreach (var thingToProcess in thingsToProcess)
{
    thingToProcess.ProcessStuff(); // This makes an API call
}

如何实现ProcessStuff()?

How do I implement ProcessStuff()?

我的第一个实现看起来像这样

My first implementation looked like this

public void ProcessStuff()
{
    var apiResponse = myHttpClient // this is an instance of HttpClient
        .GetAsync(someUrl)
        .Result;

    // do some stuff with the apiResponse
}

但是,有人告诉我,由于同步上下文而从ASP.NET之类的方法调用.Result时,以这种方式调用可能会导致死锁.

I was told however, that calling .Result in this manner can result in deadlocks when it's called from something like ASP.NET due to the synchronization context.

猜猜是什么,该批处理过程将从ASP.NET控制器开始.是的,再次,我知道,这很愚蠢.从ASP.NET运行时,它仅是批处理"一项,而不是整个批处理,但我离题了,它仍然是从ASP.NET调用的,因此我担心死锁.

Guess what, this batch process will be kicked off from an ASP.NET controller. Yes, again, I know, this is silly. When it runs from ASP.NET it's only "batch processing" one item instead of the whole batch, but I digress, it still gets called from ASP.NET and thus I'm concerned about deadlocks.

那么处理此问题的正确方法"是什么?

So what's the "right way" to handle this?

推荐答案

尝试关注-

var task = Task.Run(() => myHttpClient.GetAsync(someUrl)); 
task.Wait();
var response = task.Result;

仅在无法使用异步方法时才使用它.

Use it only when you cannot use async method.

此方法完全无死锁,如msdn博客上所述-

This method is completely deadlock free as mentioned on msdn blog- https://blogs.msdn.microsoft.com/jpsanders/2017/08/28/asp-net-do-not-use-task-result-in-main-context/

这篇关于什么是“正确方法"?同步使用HttpClient?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆