【发布时间】:2018-11-28 22:29:41
【问题描述】:
我在“正确方式”周围使用了引号,因为我已经很清楚使用异步 API 的正确方式是让异步行为在整个调用链中传播。这不是一个选项。
我正在处理一个非常庞大且复杂的系统,该系统专门设计用于在循环中同步进行批处理。
我突然使用 HttpClient 的原因是因为之前批处理的所有数据都是从 SQL 数据库中收集的,现在我们正在添加一个 Web API 调用。
是的,我们正在同步执行循环中调用 Web API。我知道。将整个事情重写为异步并不是一种选择。这实际上是我们想要做的。 (我们正在尽可能减少 API 调用的数量)
我实际上确实尝试将异步行为传播到调用链上,但后来我发现自己有 50 个文件发生了深刻的变化,仍然有数百个编译器错误需要解决,并且失去了所有希望。我被打败了。
那么,回到这个问题,鉴于微软建议不要使用 WebRequest 进行新开发,而是使用仅提供异步 API 的 HttpClient,我该怎么办?
这是我正在做的一些伪代码......
foreach (var thingToProcess in thingsToProcess)
{
thingToProcess.ProcessStuff(); // This makes an API call
}
如何实现 ProcessStuff()?
我的第一个实现是这样的
public void ProcessStuff()
{
var apiResponse = myHttpClient // this is an instance of HttpClient
.GetAsync(someUrl)
.Result;
// do some stuff with the apiResponse
}
然而,有人告诉我,以这种方式调用 .Result 可能会在从 ASP.NET 之类的东西调用时由于同步上下文而导致死锁。
猜猜看,这个批处理将从 ASP.NET 控制器启动。是的,我知道,这很愚蠢。当它从 ASP.NET 运行时,它只是“批处理”一个项目而不是整个批次,但我离题了,它仍然从 ASP.NET 调用,因此我担心死锁。
那么处理这个问题的“正确方法”是什么?
【问题讨论】:
标签: c# asynchronous async-await