<PackageReference Include="System.ClientModel" Version="1.6.1" />

ClientPipeline

public sealed class ClientPipeline
Represents an extensible pipeline used by clients that call cloud services to send and receive HTTP request and responses. Creators of ClientPipeline can modify how it process a PipelineMessage by adding PipelinePolicy instances at various points in the default pipeline.
using System.ClientModel.Internal; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Runtime.CompilerServices; using System.Threading.Tasks; namespace System.ClientModel.Primitives { [System.Runtime.CompilerServices.NullableContext(1)] [System.Runtime.CompilerServices.Nullable(0)] public sealed class ClientPipeline { [System.Runtime.CompilerServices.Nullable(0)] private struct PipelineProcessor : IReadOnlyList<PipelinePolicy>, IEnumerable<PipelinePolicy>, IEnumerable, IReadOnlyCollection<PipelinePolicy> { [System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1 })] private readonly ReadOnlyMemory<PipelinePolicy> _policies; [System.Runtime.CompilerServices.Nullable(2)] private PolicyEnumerator _enumerator; public PipelinePolicy this[int index] { get { return _policies.Span[index]; } } public int Count => _policies.Length; public PipelineProcessor([System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1 })] ReadOnlyMemory<PipelinePolicy> policies) { _enumerator = null; _policies = policies; } public IEnumerator<PipelinePolicy> GetEnumerator() { return _enumerator ?? (_enumerator = new PolicyEnumerator(this)); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } [System.Runtime.CompilerServices.Nullable(0)] private class PolicyEnumerator : IEnumerator<PipelinePolicy>, IEnumerator, IDisposable { private readonly IReadOnlyList<PipelinePolicy> _policies; private int _current; public PipelinePolicy Current { get { if (_current >= 0 && _current < _policies.Count) return _policies[_current]; throw new InvalidOperationException("'Current' is outside the bounds of the policy collection."); } } object IEnumerator.Current { get { return Current; } } public PolicyEnumerator(IReadOnlyList<PipelinePolicy> policies) { _policies = policies; _current = -1; } public bool MoveNext() { return ++_current < _policies.Count; } public void Reset() { _current = -1; } public void Dispose() { } } [System.Runtime.CompilerServices.Nullable(0)] internal class RequestOptionsProcessor : IReadOnlyList<PipelinePolicy>, IEnumerable<PipelinePolicy>, IEnumerable, IReadOnlyCollection<PipelinePolicy> { private readonly int _perCallIndex; private readonly int _perTryIndex; private readonly int _beforeTransportIndex; private readonly int _length; [System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1 })] private readonly ReadOnlyMemory<PipelinePolicy> _fixedPolicies; [System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1 })] private readonly ReadOnlyMemory<PipelinePolicy> _customPerCallPolicies; [System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1 })] private readonly ReadOnlyMemory<PipelinePolicy> _customPerTryPolicies; [System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1 })] private readonly ReadOnlyMemory<PipelinePolicy> _customBeforeTransportPolicies; [System.Runtime.CompilerServices.Nullable(2)] private PolicyEnumerator _enumerator; public PipelinePolicy this[int index] { get { TryGetPolicy(index, out PipelinePolicy policy); return policy; } } public int Count => _length; public RequestOptionsProcessor([System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1 })] ReadOnlyMemory<PipelinePolicy> fixedPolicies, [System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1 })] ReadOnlyMemory<PipelinePolicy> perCallPolicies, [System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1 })] ReadOnlyMemory<PipelinePolicy> perTryPolicies, [System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1 })] ReadOnlyMemory<PipelinePolicy> beforeTransportPolicies, int perCallIndex, int perTryIndex, int beforeTransportIndex) { _fixedPolicies = fixedPolicies; _customPerCallPolicies = perCallPolicies; _customPerTryPolicies = perTryPolicies; _customBeforeTransportPolicies = beforeTransportPolicies; _perCallIndex = perCallIndex; _perTryIndex = perTryIndex; _beforeTransportIndex = beforeTransportIndex; _length = _fixedPolicies.Length + _customPerCallPolicies.Length + _customPerTryPolicies.Length + _customBeforeTransportPolicies.Length; } public IEnumerator<PipelinePolicy> GetEnumerator() { return _enumerator ?? (_enumerator = new PolicyEnumerator(this)); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } private bool TryGetPolicy(int index, out PipelinePolicy policy) { if (TryGetFixedPerCallPolicy(index, out policy)) return true; if (TryGetCustomPerCallPolicy(index, out policy)) return true; if (TryGetFixedPerTryPolicy(index, out policy)) return true; if (TryGetCustomPerTryPolicy(index, out policy)) return true; if (TryGetFixedPerTransportPolicy(index, out policy)) return true; if (TryGetCustomBeforeTransportPolicy(index, out policy)) return true; if (TryGetFixedTransportPolicy(index, out policy)) return true; policy = null; return false; } private bool TryGetFixedPerCallPolicy(int index, out PipelinePolicy policy) { if (index < _perCallIndex) { policy = _fixedPolicies.Span[index]; return true; } policy = null; return false; } private bool TryGetCustomPerCallPolicy(int index, out PipelinePolicy policy) { if (index < _perCallIndex + _customPerCallPolicies.Length) { policy = _customPerCallPolicies.Span[index - _perCallIndex]; return true; } policy = null; return false; } private bool TryGetFixedPerTryPolicy(int index, out PipelinePolicy policy) { if (index < _perTryIndex + _customPerCallPolicies.Length) { policy = _fixedPolicies.Span[index - _customPerCallPolicies.Length]; return true; } policy = null; return false; } private bool TryGetCustomPerTryPolicy(int index, out PipelinePolicy policy) { if (index < _perTryIndex + _customPerCallPolicies.Length + _customPerTryPolicies.Length) { policy = _customPerTryPolicies.Span[index - (_perTryIndex + _customPerCallPolicies.Length)]; return true; } policy = null; return false; } private bool TryGetFixedPerTransportPolicy(int index, out PipelinePolicy policy) { if (index < _beforeTransportIndex + _customPerCallPolicies.Length + _customPerTryPolicies.Length) { policy = _fixedPolicies.Span[index - (_customPerCallPolicies.Length + _customPerTryPolicies.Length)]; return true; } policy = null; return false; } private bool TryGetCustomBeforeTransportPolicy(int index, out PipelinePolicy policy) { if (index < _beforeTransportIndex + _customPerCallPolicies.Length + _customPerTryPolicies.Length + _customBeforeTransportPolicies.Length) { policy = _customBeforeTransportPolicies.Span[index - (_beforeTransportIndex + _customPerCallPolicies.Length + _customPerTryPolicies.Length)]; return true; } policy = null; return false; } private bool TryGetFixedTransportPolicy(int index, out PipelinePolicy policy) { if (index < _length) { policy = _fixedPolicies.Span[index - (_customPerCallPolicies.Length + _customPerTryPolicies.Length + _customBeforeTransportPolicies.Length)]; return true; } policy = null; return false; } } private readonly int _perCallIndex; private readonly int _perTryIndex; private readonly int _beforeTransportIndex; [System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1 })] private readonly ReadOnlyMemory<PipelinePolicy> _policies; private readonly PipelineTransport _transport; private readonly bool _enableLogging; private readonly TimeSpan _networkTimeout; internal static TimeSpan DefaultNetworkTimeout { get; } = TimeSpan.FromSeconds(100); private ClientPipeline([System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1 })] ReadOnlyMemory<PipelinePolicy> policies, TimeSpan networkTimeout, int perCallIndex, int perTryIndex, int beforeTransportIndex, bool enableLogging) { ReadOnlySpan<PipelinePolicy> span = policies.Span; if (!(span[policies.Length - 1] is PipelineTransport)) throw new ArgumentException("The last policy must be of type 'PipelineTransport'.", "policies"); span = policies.Span; _transport = (PipelineTransport)span[policies.Length - 1]; _policies = policies; _perCallIndex = perCallIndex; _perTryIndex = perTryIndex; _beforeTransportIndex = beforeTransportIndex; _networkTimeout = networkTimeout; _enableLogging = enableLogging; } public static ClientPipeline Create([System.Runtime.CompilerServices.Nullable(2)] ClientPipelineOptions options = null) { return Create(options ?? ClientPipelineOptions.Default, ReadOnlySpan<PipelinePolicy>.Empty, ReadOnlySpan<PipelinePolicy>.Empty, ReadOnlySpan<PipelinePolicy>.Empty); } public static ClientPipeline Create(ClientPipelineOptions options, [System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1 })] ReadOnlySpan<PipelinePolicy> perCallPolicies, [System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1 })] ReadOnlySpan<PipelinePolicy> perTryPolicies, [System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1 })] ReadOnlySpan<PipelinePolicy> beforeTransportPolicies) { Argument.AssertNotNull(options, "options"); options.Freeze(); options.ClientLoggingOptions?.ValidateOptions(); int num = perCallPolicies.Length + perTryPolicies.Length + beforeTransportPolicies.Length; PipelinePolicy[] perTryPolicies2 = options.PerTryPolicies; int num2 = num + ((perTryPolicies2 != null) ? perTryPolicies2.Length : 0); PipelinePolicy[] perCallPolicies2 = options.PerCallPolicies; int num3 = num2 + ((perCallPolicies2 != null) ? perCallPolicies2.Length : 0); PipelinePolicy[] beforeTransportPolicies2 = options.BeforeTransportPolicies; PipelinePolicy[] array = new PipelinePolicy[num3 + ((beforeTransportPolicies2 != null) ? beforeTransportPolicies2.Length : 0) + 1 + (options.AddMessageLoggingPolicy ? 1 : 0) + 1]; int num4 = 0; perCallPolicies.CopyTo(array.AsSpan(num4)); num4 += perCallPolicies.Length; if (options.PerCallPolicies != null) { options.PerCallPolicies.CopyTo(array.AsSpan(num4)); num4 += options.PerCallPolicies.Length; } int perCallIndex = num4; array[num4++] = (options.RetryPolicy ?? options.GetClientRetryPolicy()); perTryPolicies.CopyTo(array.AsSpan(num4)); num4 += perTryPolicies.Length; if (options.PerTryPolicies != null) { options.PerTryPolicies.CopyTo(array.AsSpan(num4)); num4 += options.PerTryPolicies.Length; } int perTryIndex = num4; if (options.AddMessageLoggingPolicy) array[num4++] = (options.MessageLoggingPolicy ?? options.GetMessageLoggingPolicy()); beforeTransportPolicies.CopyTo(array.AsSpan(num4)); num4 += beforeTransportPolicies.Length; if (options.BeforeTransportPolicies != null) { options.BeforeTransportPolicies.CopyTo(array.AsSpan(num4)); num4 += options.BeforeTransportPolicies.Length; } int beforeTransportIndex = num4; array[num4++] = (options.Transport ?? options.GetHttpClientPipelineTransport()); bool valueOrDefault = (options.ClientLoggingOptions?.EnableLogging).GetValueOrDefault(true); return new ClientPipeline(array, options.NetworkTimeout ?? DefaultNetworkTimeout, perCallIndex, perTryIndex, beforeTransportIndex, valueOrDefault); } public PipelineMessage CreateMessage() { PipelineMessage pipelineMessage = _transport.CreateMessage(); pipelineMessage.NetworkTimeout = _networkTimeout; return pipelineMessage; } public PipelineMessage CreateMessage(Uri uri, string method, [System.Runtime.CompilerServices.Nullable(2)] PipelineMessageClassifier classifier = null) { Argument.AssertNotNull(uri, "uri"); Argument.AssertNotNull(method, "method"); PipelineMessage pipelineMessage = CreateMessage(); pipelineMessage.Request.Uri = uri; pipelineMessage.Request.Method = method; pipelineMessage.ResponseClassifier = (classifier ?? PipelineMessageClassifier.Default); return pipelineMessage; } public void Send(PipelineMessage message) { Argument.AssertNotNull(message, "message"); message.Request.ClientRequestId = (Activity.Current?.Id ?? Guid.NewGuid().ToString()); IReadOnlyList<PipelinePolicy> processor = GetProcessor(message); processor[0].Process(message, processor, 0); } [AsyncStateMachine(typeof(<SendAsync>d__16))] public ValueTask SendAsync(PipelineMessage message) { <SendAsync>d__16 stateMachine = default(<SendAsync>d__16); stateMachine.<>t__builder = AsyncValueTaskMethodBuilder.Create(); stateMachine.<>4__this = this; stateMachine.message = message; stateMachine.<>1__state = -1; stateMachine.<>t__builder.Start(ref stateMachine); return stateMachine.<>t__builder.Task; } private IReadOnlyList<PipelinePolicy> GetProcessor(PipelineMessage message) { if (message.UseCustomRequestPipeline) return new RequestOptionsProcessor(_policies, message.PerCallPolicies, message.PerTryPolicies, message.BeforeTransportPolicies, _perCallIndex, _perTryIndex, _beforeTransportIndex); return new PipelineProcessor(_policies); } } }