C# 如何在并行运行时获取HttpClient响应时间

C# 如何在并行运行时获取HttpClient响应时间,c#,asynchronous,task-parallel-library,C#,Asynchronous,Task Parallel Library,在我的ASP.NET MVC4应用程序中,我有一个控制器动作,在这个动作中,我去几个外部网站,收集我在页面上以聚合方式显示的信息。显然,我想并行地完成这项工作,因此我编写了类似于以下内容的代码: var client1 = new HttpClient().GetAsync("http://google.com"); var client2 = new HttpClient().GetAsync("http://stackoverflow.com"); var client3 = new Htt

在我的ASP.NET MVC4应用程序中,我有一个控制器动作,在这个动作中,我去几个外部网站,收集我在页面上以聚合方式显示的信息。显然,我想并行地完成这项工作,因此我编写了类似于以下内容的代码:

var client1 = new HttpClient().GetAsync("http://google.com");
var client2 = new HttpClient().GetAsync("http://stackoverflow.com");
var client3 = new HttpClient().GetAsync("http://twitter.com");

var result1 = client1.Result;
var result2 = client2.Result;
var result3 = client3.Result;

如何找出每个请求完成所需的时间,以便在页面上显示这些信息?

我可能会尝试以下方法:

private async void _HttpServerDemo()
{
    var info1 = _GetHttpWithTimingInfo("http://google.com");
    var info2 = _GetHttpWithTimingInfo("http://stackoverflow.com");
    var info3 = _GetHttpWithTimingInfo("http://twitter.com");

    await Task.WhenAll(info1, info2, info3);
    Console.WriteLine("Request1 took {0}", info1.Result);
    Console.WriteLine("Request2 took {0}", info2.Result);
    Console.WriteLine("Request3 took {0}", info3.Result);
}

private async Task<Tuple<HttpResponseMessage, TimeSpan>> _GetHttpWithTimingInfo(string url)
{
    var stopWatch = Stopwatch.StartNew();
    using (var client = new HttpClient())
    {
        var result = await client.GetAsync(url);
        return new Tuple<HttpResponseMessage, TimeSpan>(result, stopWatch.Elapsed);
    }
}
private async void\u HttpServerDemo()
{
var info1=\u GetHttpWithTimingInfo(“http://google.com");
var info2=_GetHttpWithTimingInfo(“http://stackoverflow.com");
var info3=_GetHttpWithTimingInfo(“http://twitter.com");
等待任务。WhenAll(info1,info2,info3);
WriteLine(“Request1接受了{0}”,info1.Result);
WriteLine(“Request2接受了{0}”,info2.Result);
WriteLine(“Request3接受了{0}”,info3.Result);
}
专用异步任务\u GetHttpWithTimingInfo(字符串url)
{
var stopWatch=stopWatch.StartNew();
使用(var client=new HttpClient())
{
var result=await client.GetAsync(url);
返回新的元组(结果,stopWatch.appeased);
}
}

现在,在.NET Core中有一个选项可以为您提供更好的结果,至少在我的情况下,所用时间比使用。我会坚持他的建议,但把秒表移到了管理人那里

例如,您可以使用DelegatingHandler

您仍然可以按照上面的建议使用秒表,但可以在处理程序中使用秒表。我将经过的时间添加到标题中,然后在例如您的_GetHttpWithTimingInfo中检索该标题并进一步处理。最有可能的情况是,您可以DI一些服务,并将持续时间从处理程序本身保存到数据库中,具体取决于您的项目

也许,这个解决方案也可以解决前面提到的问题

此外,此方法直接用于checkSendAsync。请注意,他们使用的是内部值秒表,而不是秒表

这些日志在处理程序中使用秒表显示,而在方法中直接使用秒表显示:

08-11-2020 18:05:52.024 [INF] Handler: 992, _GetHttpWithTimingInfo 995
08-11-2020 18:05:52.153 [INF] Handler: 663, _GetHttpWithTimingInfo 1249
08-11-2020 18:05:52.208 [INF] Handler: 999, _GetHttpWithTimingInfo 1220
08-11-2020 18:05:52.219 [INF] Handler: 1002, _GetHttpWithTimingInfo 1241
08-11-2020 18:05:52.219 [INF] Handler: 989, _GetHttpWithTimingInfo 1217
08-11-2020 18:05:52.255 [INF] Handler: 609, _GetHttpWithTimingInfo 1302
08-11-2020 18:05:52.260 [INF] Handler: 959, _GetHttpWithTimingInfo 1267
08-11-2020 18:05:52.287 [INF] Handler: 1063, _GetHttpWithTimingInfo 1303
08-11-2020 18:05:52.292 [INF] Handler: 515, _GetHttpWithTimingInfo 1381
08-11-2020 18:05:52.296 [INF] Handler: 992, _GetHttpWithTimingInfo 1286
08-11-2020 18:05:52.321 [INF] Handler: 953, _GetHttpWithTimingInfo 1323
08-11-2020 18:05:52.324 [INF] Handler: 973, _GetHttpWithTimingInfo 1304
08-11-2020 18:05:52.326 [INF] Handler: 985, _GetHttpWithTimingInfo 1302

为什么方法名称以
开头?我在C#中还没有见过这样的命名约定,即使是对于
private
方法也是如此。@swick:我在框架开发方面做了大量工作,这是一种很好的方法,可以快速查看某些东西是私有的还是公共的。然而,这并不总是需要的,为了进一步了解,这个问题的答案中的共识似乎是不使用下划线作为私有方法。这可能会导致错误的结果。如果没有线程就绪(或上下文在其他地方使用),等待将不会持续一段时间-导致返回的时间跨度高于响应时间。我使用此方法。如果您启动20多个并行请求,它会显著失败。单个线程可能会等待一秒钟(!!!)之后才有机会停止计时器。公平地说,我仍然不知道更好的方法…并行不等于异步!你能提供一个示例实现吗?提供它可能需要一些时间。我会试试。