{
public partial class HttpClientHandler : HttpMessageHandler
{
- private readonly SocketsHttpHandler? _socketHandler;
+ private static readonly ConcurrentDictionary<string, MethodInfo?> s_cachedMethods = new();
+
private readonly HttpMessageHandler? _nativeHandler;
- private MetricsHandler? _metricsHandler;
+ private IMeterFactory? _nativeMeterFactory;
+ private MetricsHandler? _nativeMetricsHandler;
- private static readonly ConcurrentDictionary<string, MethodInfo?> s_cachedMethods =
- new ConcurrentDictionary<string, MethodInfo?>();
+ private readonly SocketsHttpHandler? _socketHandler;
- private IMeterFactory? _meterFactory;
private ClientCertificateOption _clientCertificateOptions;
private volatile bool _disposed;
+ private HttpMessageHandler Handler
+ {
+ get
+ {
+ if (IsNativeHandlerEnabled)
+ {
+ if (_nativeMetricsHandler is null)
+ {
+ // We only setup these handlers for the native handler. SocketsHttpHandler already does this internally.
+ HttpMessageHandler handler = _nativeHandler!;
+
+ if (DiagnosticsHandler.IsGloballyEnabled())
+ {
+ handler = new DiagnosticsHandler(handler, DistributedContextPropagator.Current);
+ }
+
+ MetricsHandler metricsHandler = new MetricsHandler(handler, _nativeMeterFactory, out _);
+
+ // Ensure a single handler is used for all requests.
+ if (Interlocked.CompareExchange(ref _nativeMetricsHandler, metricsHandler, null) != null)
+ {
+ handler.Dispose();
+ }
+ }
+
+ return _nativeMetricsHandler;
+ }
+ else
+ {
+ return _socketHandler!;
+ }
+ }
+ }
+
public HttpClientHandler()
{
if (IsNativeHandlerEnabled)
[CLSCompliant(false)]
public IMeterFactory? MeterFactory
{
- get => _meterFactory;
+ get
+ {
+ if (IsNativeHandlerEnabled)
+ {
+ return _nativeMeterFactory;
+ }
+ else
+ {
+ return _socketHandler!.MeterFactory;
+ }
+ }
set
{
ObjectDisposedException.ThrowIf(_disposed, this);
- if (_metricsHandler != null)
+
+ if (IsNativeHandlerEnabled)
{
- throw new InvalidOperationException(SR.net_http_operation_started);
+ if (_nativeMetricsHandler is not null)
+ {
+ throw new InvalidOperationException(SR.net_http_operation_started);
+ }
+
+ _nativeMeterFactory = value;
+ }
+ else
+ {
+ _socketHandler!.MeterFactory = value;
}
- _meterFactory = value;
}
}
CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(request);
- MetricsHandler handler = _metricsHandler ?? SetupHandlerChain();
- return handler.SendAsync(request, cancellationToken);
+ return Handler.SendAsync(request, cancellationToken);
}
// lazy-load the validator func so it can be trimmed by the ILLinker if it isn't used.
}
}
- private MetricsHandler SetupHandlerChain()
- {
- HttpMessageHandler handler = IsNativeHandlerEnabled ? _nativeHandler! : _socketHandler!;
- if (DiagnosticsHandler.IsGloballyEnabled())
- {
- handler = new DiagnosticsHandler(handler, DistributedContextPropagator.Current);
- }
- MetricsHandler metricsHandler = new MetricsHandler(handler, _meterFactory, out _);
-
- // Ensure a single handler is used for all requests.
- if (Interlocked.CompareExchange(ref _metricsHandler, metricsHandler, null) != null)
- {
- handler.Dispose();
- }
- return _metricsHandler;
- }
-
private void ThrowForModifiedManagedSslOptionsIfStarted()
{
// Hack to trigger an InvalidOperationException if a property that's stored on