场景
我需要在网页上显示N个报告。需要向外部服务请求报告。服务生成报告的时间可能从 2 秒到 50 秒不等,具体取决于请求的内容。
要调用服务,我在 async 操作中使用 HttpClient。为了生成 1 份报告,我调用该服务一次。为了生成 5 份报告,我调用它 5 次,依此类推。
问题
假设我们请求 3 个报告BigReport、MediumReport 和 SmallReport,已知相对生成时间为 1 分钟、30 秒和 2 秒,我们按以下顺序调用服务:
大报表、中型报表、小报表
HttpCalls 的结果如下:
基本上,虽然 HttpCall 有所不同,但事实上它们是在很短的时间内发出的,并且它们仍然是“活动的”,服务器将基于“先到先服务”来响应,而不是为每个调用提供服务及其准确的反应。
代码我有一个带有异步操作的请求控制器,如下所示:
public async Task<string> GenerateReport(string blockContent)
{
var formDataContent = new MultipartFormDataContent
{
AddStringContent(userid, "userid"),
AddStringContent(passcode, "passcode"),
AddStringContent(outputtype, "outputtype"),
AddStringContent(submit, "submit")
};
var blockStream = new StreamContent(new MemoryStream(Encoding.Default.GetBytes(blockContent)));
blockStream.Headers.Add("Content-Disposition", "form-data; name=\"file\"; filename=\"" + filename + "\"");
formDataContent.Add(blockStream);
using (var client = new HttpClient())
{
using(var message = await client.PostAsync(Url, formDataContent))
{
var report = await message.Content.ReadAsStringAsync();
return report;
}
}
}
该操作是通过 Ajax 从视图中调用的,如下所示
//FOREACH BLOCK, CALL THE REPORT SERVICE
$('.block').each(function(index, block) {
var reportActionUrl = "Report/GenerateReport/"+block.Content;
//AJAX CALL GetReportAction
$(block).load(reportActionUrl);
});
如果我通过删除异步任务将操作从异步转换为同步,一切都会正常工作,而不是“等待”响应,我只是得到结果
var result = client.PostAsync(Url, formDataContent).Result.
这将使一切同步运行并正常工作,但用户的等待时间会更长。我真的很想通过并行调用或类似的方式来避免这种情况。结论与问题
在使用 Fiddler 检查之后,问题本身是有道理的,因为我们几乎同时有多个打开的 HttpRequest 处于待处理状态。 我想我需要一种
handler或 something 来识别和匹配请求/响应,但我不知道我需要查找的“域”的名称是什么。到目前为止,我的问题是:
“并行进行多个http调用”的技术名称是什么?
问题在于文件名参数被错误地称为
filename而不是 blockname。这导致了非常奇怪的行为,因为一个文件可能有很多块。 吸取的教训是,如果出现非常奇怪的行为,在这种情况下,使用 HttpClient 调用,分析所有可能的参数并使用不同的值进行测试,即使它没有太大意义。最坏的情况下它可能会抛出错误。