- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用 MS Graph API 将数百万用户从本地 AD 迁移到 Azure AD B2C,以在 B2C 中创建用户。我编写了一个 .Net Core 3.1 控制台应用程序来执行此迁移。为了加快速度,我正在对 Graph API 进行并发调用。这工作得很好 - 有点。
在开发过程中,我从 Visual Studio 2019 运行时体验到了可接受的性能,但对于测试,我是从 Powershell 7 中的命令行运行的。从 Powershell 并发调用 HttpClient 的性能非常糟糕。从 Powershell 运行时,HttpClient 允许的并发调用数量似乎存在限制,因此大于 40 到 50 个请求的并发批处理中的调用开始堆积。它似乎正在运行 40 到 50 个并发请求,同时阻止其余请求。
我不是在寻求异步编程方面的帮助。我正在寻找一种方法来解决 Visual Studio 运行时行为和 Powershell 命令行运行时行为之间的差异。从 Visual Studio 的绿色箭头按钮在 Release模式下运行的行为符合预期。从命令行运行不会。
我用异步调用填充任务列表,然后等待 Task.WhenAll(tasks)。每次调用需要 300 到 400 毫秒。从 Visual Studio 运行时,它按预期工作。我同时进行了 1000 个调用,每个调用都在预期时间内单独完成。整个任务 block 只比最长的单个调用长几毫秒。
当我从 Powershell 命令行运行相同的构建时,行为会发生变化。前 40 到 50 次调用预计需要 300 到 400 毫秒,但随后各个调用时间会增加到 20 秒。我认为这些调用正在序列化,因此一次只执行 40 到 50 个,而其他调用则在等待。
经过数小时的反复试验,我能够将其范围缩小到 HttpClient。为了隔离问题,我使用一个执行 Task.Delay(300) 并返回模拟结果的方法模拟了对 HttpClient.SendAsync 的调用。在这种情况下,从控制台运行与从 Visual Studio 运行的行为相同。
我正在使用 IHttpClientFactory,我什至尝试调整 ServicePointManager 的连接限制。
这是我的注册码。
public static IServiceCollection RegisterHttpClient(this IServiceCollection services, int batchSize)
{
ServicePointManager.DefaultConnectionLimit = batchSize;
ServicePointManager.MaxServicePoints = batchSize;
ServicePointManager.SetTcpKeepAlive(true, 1000, 5000);
services.AddHttpClient(MSGraphRequestManager.HttpClientName, c =>
{
c.Timeout = TimeSpan.FromSeconds(360);
c.DefaultRequestHeaders.Add("User-Agent", "xxxxxxxxxxxx");
})
.ConfigurePrimaryHttpMessageHandler(() => new DefaultHttpClientHandler(batchSize));
return services;
}
internal class DefaultHttpClientHandler : HttpClientHandler
{
public DefaultHttpClientHandler(int maxConnections)
{
this.MaxConnectionsPerServer = maxConnections;
this.UseProxy = false;
this.AutomaticDecompression = System.Net.DecompressionMethods.GZip | System.Net.DecompressionMethods.Deflate;
}
}
var timer = Stopwatch.StartNew();
var tasks = new Task<(UpsertUserResult, TimeSpan)>[users.Length];
for (var i = 0; i < users.Length; ++i)
{
tasks[i] = this.CreateUserAsync(users[i]);
}
var results = await Task.WhenAll(tasks);
timer.Stop();
var httpClient = this.httpClientFactory.CreateClient(HttpClientName);
#if use_http
using var response = await httpClient.SendAsync(request);
#else
await Task.Delay(300);
var graphUser = new User { Id = "mockid" };
using var response = new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(JsonConvert.SerializeObject(graphUser)) };
#endif
var responseContent = await response.Content.ReadAsStringAsync();
最佳答案
我想到了两件事。大多数 microsoft powershell 是在版本 1 和 2 中编写的。版本 1 和 2 具有 MTA 的 System.Threading.Thread.ApartmentState。在版本 3 到 5 中,公寓状态默认更改为 STA。
第二个想法是听起来他们正在使用 System.Threading.ThreadPool 来管理线程。你的线程池有多大?
如果这些不能解决问题,请开始在 System.Threading 下挖掘。
当我读到你的问题时,我想到了这个博客。 https://devblogs.microsoft.com/oldnewthing/20170623-00/?p=96455
一位同事演示了一个创建一千个工作项的示例程序,每个工作项都模拟一个需要 500 毫秒才能完成的网络调用。在第一个演示中,网络调用是阻塞同步调用,示例程序将线程池限制为十个线程,以使效果更加明显。在这种配置下,前几个工作项被快速分派(dispatch)到线程,但随后由于没有更多线程可用于服务新工作项,延迟开始增加,因此剩余的工作项必须等待越来越长的时间才能让线程可以为它服务。工作项开始的平均延迟超过两分钟。
更新1:
我从开始菜单运行 PowerShell 7.0,线程状态为 STA。两个版本的线程状态是否不同?
PS C:\Program Files\PowerShell\7> [System.Threading.Thread]::CurrentThread
ManagedThreadId : 12
IsAlive : True
IsBackground : False
IsThreadPoolThread : False
Priority : Normal
ThreadState : Running
CurrentCulture : en-US
CurrentUICulture : en-US
ExecutionContext : System.Threading.ExecutionContext
Name : Pipeline Execution Thread
ApartmentState : STA
PS C:\Windows\system32> [System.Net.ServicePointManager].GetProperties() | select name
Name
----
SecurityProtocol
MaxServicePoints
DefaultConnectionLimit
MaxServicePointIdleTime
UseNagleAlgorithm
Expect100Continue
EnableDnsRoundRobin
DnsRefreshTimeout
CertificatePolicy
ServerCertificateValidationCallback
ReusePort
CheckCertificateRevocationList
EncryptionPolicy
In addition, every HttpClient instance uses its own connection pool, isolating its requests from requests executed by other HttpClient instances.
If an app using HttpClient and related classes in the Windows.Web.Http namespace downloads large amounts of data (50 megabytes or more), then the app should stream those downloads and not use the default buffering. If the default buffering is used the client memory usage will get very large, potentially resulting in reduced performance.
Add-Type -AssemblyName System.Net.Http
$client = New-Object -TypeName System.Net.Http.Httpclient
$client | format-list *
DefaultRequestHeaders : {}
BaseAddress :
Timeout : 00:01:40
MaxResponseContentBufferSize : 2147483647
关于c# - 在 Powershell 中运行时与在 Visual Studio 中运行时的 HttpClient 并发行为不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60707843/
我看到很多人发布关于 NullInjectorError: No provider for HttpClient! 的问题但是我在 Karma 单元测试中遇到了更具描述性的错误。我一直在学习 Angu
全部, 我创造: public static final HttpClient DEFAULT_HTTPCLIENT = HttpClients .createDefault(); f
我正在使用 HttpClient fluent api 编写验收测试,但遇到了一些麻烦。 @When("^I submit delivery address and delivery time$")
有人可以分享如何配置现代 HttpClient 4.5.3 以重试失败的请求并在每次重试前等待一段时间吗? 到目前为止,我似乎正确理解了 .setRetryHandler(new DefaultHtt
我在使用 java 中的 HttpClient 库时遇到问题。 目标网站在 SSL ( https://www.betcris.com ) 上,我可以从该网站加载索引页面就好了。 但是,显示不同运动赔
所以我的应用涉及大量网络调用(可能连接到 10 个不同的服务器)和获取数据。从我读过的几篇文章中,建议重用 HTTPClient 实例,因为它可以防止资源(套接字等)的浪费。但是我发现围绕可扩展且健壮
我正在调用一个外部 API,并希望我的 API 可以进行单元测试。为此,我正在尝试包装 HttpClient。我现在只需要一种方法。 这是我的界面。 public interface IHttpCli
出于调试目的,我希望看到将要发送的原始请求。有没有一种方法可以直接从 HttpPost 或 HttpClient 的API中获得没有HTTP监视器的信息? 我发现了一些“几乎”重复的问题,但不是针对这
我正在尝试在小型 WebAssemply 应用程序(使用 .NET 5 创建)中测试 HttpClient。program.cs 包含以下语句来添加 HttpClient 服务: builder.Se
我在 Application_Start 事件中创建了 HttpClient 的单个实例,以便在 Global.asax.cs 中的应用程序中重用 应用程序启动中的代码: protected
我对此有点新手...基本上我需要运行一个脚本来从谷歌趋势下载.csv 文件。我按照这个reference写了下面的代码,代码如下: HttpClient client = new Defau
我正在尝试实现一个基本的 1 spout - 1 bolt Storm 拓扑。我有一个 Storm Bolt,可以使用 Apache HttpClient (4.3.1) 发出 HTTP 请求。但是,
我正在尝试在我的 Xamarin.Forms 移动应用程序中使用 HttpClient 创建网络服务层。 没有单例模式 单例模式 在第一种方法中,我在每个新请求中创建新的 http 客户端对象通过移动
在下面的示例中,我创建了一个 Java 11 httpClient,然后创建了多个并发 HttpRequest。 这是不好的做法吗? 每个 HttpRequest 都应该有自己的 HttpClient
我正在开发一个 Drupal 8 自定义模块。我在任何节点类型中都有两个字段(url 和文本 html 字段)。这是该模块所期望的功能: 该模块将抓取“url字段”的页面并复制html代码以将它们粘贴
我正在为 httpclient 使用 apache httpcompnonents 库。我想在多线程应用程序中使用它,其中线程数会非常高,并且会有频繁的 http 调用。这是我用来在执行调用后读取响应
最近我将我的代码库从 .net core 1.0 迁移到 2.0 。之后,我随机收到错误 “使用 System.Net.Http.HttpClient 时服务器返回无效或无法识别的响应错误”。我在 1
我有该代码: while(!lastPage && currentPage < maxPageSize){ StringBuilder request = new Strin
我的应用程序使用 Apache HTTPClient 4.3.5 发送 HTTP 请求并获得响应。 我想弄清楚应用程序收到了什么响应。 以下是日志片段- [Jan 04 2015 05:38:14.1
如何从 HttpClient 类型的现有对象获取 cookie? 我正在使用 HttpClient 版本 4.3.3,它不再有方法 httpClient.getCookieStore() 了。 最佳答
我是一名优秀的程序员,十分优秀!