@@ -54,28 +54,18 @@ protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage
54
54
{
55
55
_ = Throw . IfNull ( request ) ;
56
56
57
- var pipeline = _pipelineProvider ( request ) ;
58
- var created = false ;
59
- if ( request . GetResilienceContext ( ) is not ResilienceContext context )
60
- {
61
- context = ResilienceContextPool . Shared . Get ( cancellationToken ) ;
62
- created = true ;
63
- request . SetResilienceContext ( context ) ;
64
- }
57
+ ResiliencePipeline < HttpResponseMessage > pipeline = _pipelineProvider ( request ) ;
65
58
66
- if ( request . GetRequestMetadata ( ) is RequestMetadata requestMetadata )
67
- {
68
- context . Properties . Set ( ResilienceKeys . RequestMetadata , requestMetadata ) ;
69
- }
70
-
71
- context . Properties . Set ( ResilienceKeys . RequestMessage , request ) ;
59
+ ResilienceContext context = GetOrSetResilienceContext ( request , cancellationToken , out bool created ) ;
60
+ TrySetRequestMetadata ( context , request ) ;
61
+ SetRequestMessage ( context , request ) ;
72
62
73
63
try
74
64
{
75
- var outcome = await pipeline . ExecuteOutcomeAsync (
65
+ Outcome < HttpResponseMessage > outcome = await pipeline . ExecuteOutcomeAsync (
76
66
static async ( context , state ) =>
77
67
{
78
- var request = context . Properties . GetValue ( ResilienceKeys . RequestMessage , state . request ) ;
68
+ HttpRequestMessage request = GetRequestMessage ( context , state . request ) ;
79
69
80
70
// Always re-assign the context to this request message before execution.
81
71
// This is because for primary actions the context is also cloned and we need to re-assign it
@@ -84,7 +74,10 @@ static async (context, state) =>
84
74
85
75
try
86
76
{
87
- var response = await state . instance . SendCoreAsync ( request , context . CancellationToken ) . ConfigureAwait ( context . ContinueOnCapturedContext ) ;
77
+ HttpResponseMessage response = await state . instance
78
+ . SendCoreAsync ( request , context . CancellationToken )
79
+ . ConfigureAwait ( context . ContinueOnCapturedContext ) ;
80
+
88
81
return Outcome . FromResult ( response ) ;
89
82
}
90
83
#pragma warning disable CA1031 // Do not catch general exception types
@@ -104,19 +97,99 @@ static async (context, state) =>
104
97
}
105
98
finally
106
99
{
107
- if ( created )
108
- {
109
- ResilienceContextPool . Shared . Return ( context ) ;
110
- request . SetResilienceContext ( null ) ;
111
- }
112
- else
113
- {
114
- // Restore the original context
115
- request . SetResilienceContext ( context ) ;
116
- }
100
+ RestoreResilienceContext ( context , request , created ) ;
101
+ }
102
+ }
103
+
104
+ #if NET6_0_OR_GREATER
105
+ /// <summary>
106
+ /// Sends an HTTP request to the inner handler to send to the server as a synchronous operation.
107
+ /// </summary>
108
+ /// <param name="request">The HTTP request message to send to the server.</param>
109
+ /// <param name="cancellationToken">A cancellation token to cancel operation.</param>
110
+ /// <returns>An HTTP response received from the server.</returns>
111
+ /// <exception cref="ArgumentNullException">If <paramref name="request"/> is <see langword="null"/>.</exception>
112
+ protected override HttpResponseMessage Send ( HttpRequestMessage request , CancellationToken cancellationToken )
113
+ {
114
+ _ = Throw . IfNull ( request ) ;
115
+
116
+ ResiliencePipeline < HttpResponseMessage > pipeline = _pipelineProvider ( request ) ;
117
+
118
+ ResilienceContext context = GetOrSetResilienceContext ( request , cancellationToken , out bool created ) ;
119
+ TrySetRequestMetadata ( context , request ) ;
120
+ SetRequestMessage ( context , request ) ;
121
+
122
+ try
123
+ {
124
+ return pipeline . Execute (
125
+ static ( context , state ) =>
126
+ {
127
+ HttpRequestMessage request = GetRequestMessage ( context , state . request ) ;
128
+
129
+ // Always re-assign the context to this request message before execution.
130
+ // This is because for primary actions the context is also cloned and we need to re-assign it
131
+ // here because Polly doesn't have any other events that we can hook into.
132
+ request . SetResilienceContext ( context ) ;
133
+
134
+ return state . instance . SendCore ( request , context . CancellationToken ) ;
135
+ } ,
136
+ context ,
137
+ ( instance : this , request ) ) ;
138
+ }
139
+ finally
140
+ {
141
+ RestoreResilienceContext ( context , request , created ) ;
142
+ }
143
+ }
144
+ #endif
145
+
146
+ private static ResilienceContext GetOrSetResilienceContext ( HttpRequestMessage request , CancellationToken cancellationToken , out bool created )
147
+ {
148
+ created = false ;
149
+
150
+ if ( request . GetResilienceContext ( ) is not ResilienceContext context )
151
+ {
152
+ context = ResilienceContextPool . Shared . Get ( cancellationToken ) ;
153
+ created = true ;
154
+ request . SetResilienceContext ( context ) ;
155
+ }
156
+
157
+ return context ;
158
+ }
159
+
160
+ private static void TrySetRequestMetadata ( ResilienceContext context , HttpRequestMessage request )
161
+ {
162
+ if ( request . GetRequestMetadata ( ) is RequestMetadata requestMetadata )
163
+ {
164
+ context . Properties . Set ( ResilienceKeys . RequestMetadata , requestMetadata ) ;
165
+ }
166
+ }
167
+
168
+ private static void SetRequestMessage ( ResilienceContext context , HttpRequestMessage request )
169
+ => context . Properties . Set ( ResilienceKeys . RequestMessage , request ) ;
170
+
171
+ private static HttpRequestMessage GetRequestMessage ( ResilienceContext context , HttpRequestMessage request )
172
+ => context . Properties . GetValue ( ResilienceKeys . RequestMessage , request ) ;
173
+
174
+ private static void RestoreResilienceContext ( ResilienceContext context , HttpRequestMessage request , bool created )
175
+ {
176
+ if ( created )
177
+ {
178
+ ResilienceContextPool . Shared . Return ( context ) ;
179
+ request . SetResilienceContext ( null ) ;
180
+ }
181
+ else
182
+ {
183
+ // Restore the original context
184
+ request . SetResilienceContext ( context ) ;
117
185
}
118
186
}
119
187
120
188
private Task < HttpResponseMessage > SendCoreAsync ( HttpRequestMessage requestMessage , CancellationToken cancellationToken )
121
189
=> base . SendAsync ( requestMessage , cancellationToken ) ;
190
+
191
+ #if NET6_0_OR_GREATER
192
+ private HttpResponseMessage SendCore ( HttpRequestMessage requestMessage , CancellationToken cancellationToken )
193
+ => base . Send ( requestMessage , cancellationToken ) ;
194
+ #endif
122
195
}
0 commit comments