@@ -23,7 +23,7 @@ public class Rpc : IRpc
23
23
private readonly ITypeNameSerializer typeNameSerializer ;
24
24
25
25
private readonly object responseQueuesAddLock = new object ( ) ;
26
- private readonly ConcurrentDictionary < RpcKey , string > responseQueues = new ConcurrentDictionary < RpcKey , string > ( ) ;
26
+ private readonly ConcurrentDictionary < RpcKey , ResponseQueueWithCancellation > responseQueues = new ConcurrentDictionary < RpcKey , ResponseQueueWithCancellation > ( ) ;
27
27
private readonly ConcurrentDictionary < string , ResponseAction > responseActions = new ConcurrentDictionary < string , ResponseAction > ( ) ;
28
28
29
29
protected readonly TimeSpan disablePeriodicSignaling = TimeSpan . FromMilliseconds ( - 1 ) ;
@@ -63,11 +63,19 @@ public Rpc(
63
63
64
64
private void OnConnectionCreated ( ConnectionCreatedEvent @event )
65
65
{
66
+ var copyOfResponseQueues = responseQueues . Values ;
67
+ responseQueues . Clear ( ) ;
68
+
66
69
var copyOfResponseActions = responseActions . Values ;
67
70
responseActions . Clear ( ) ;
68
- responseQueues . Clear ( ) ;
69
71
70
- // retry in-flight requests.
72
+ // call consumer cancellations
73
+ foreach ( var queueWithCancellation in copyOfResponseQueues )
74
+ {
75
+ queueWithCancellation . Cancellation . Dispose ( ) ;
76
+ }
77
+
78
+ // finish in-flight requests
71
79
foreach ( var responseAction in copyOfResponseActions )
72
80
{
73
81
responseAction . OnFailure ( ) ;
@@ -85,7 +93,11 @@ public virtual Task<TResponse> Request<TRequest, TResponse>(TRequest request, Ac
85
93
var configuration = new RequestConfiguration ( ) ;
86
94
configure ( configuration ) ;
87
95
96
+ #if NETFX && ! NET46
88
97
var tcs = new TaskCompletionSource < TResponse > ( ) ;
98
+ #else
99
+ var tcs = new TaskCompletionSource < TResponse > ( TaskCreationOptions . RunContinuationsAsynchronously ) ;
100
+ #endif
89
101
90
102
var timeout = timeoutStrategy . GetTimeoutSeconds ( requestType ) ;
91
103
Timer timer = null ;
@@ -154,13 +166,12 @@ protected virtual string SubscribeToResponse<TRequest, TResponse>()
154
166
{
155
167
var responseType = typeof ( TResponse ) ;
156
168
var rpcKey = new RpcKey { Request = typeof ( TRequest ) , Response = responseType } ;
157
- string queueName ;
158
- if ( responseQueues . TryGetValue ( rpcKey , out queueName ) )
159
- return queueName ;
169
+ if ( responseQueues . TryGetValue ( rpcKey , out ResponseQueueWithCancellation queueWithCancellation ) )
170
+ return queueWithCancellation . QueueName ;
160
171
lock ( responseQueuesAddLock )
161
172
{
162
- if ( responseQueues . TryGetValue ( rpcKey , out queueName ) )
163
- return queueName ;
173
+ if ( responseQueues . TryGetValue ( rpcKey , out queueWithCancellation ) )
174
+ return queueWithCancellation . QueueName ;
164
175
165
176
var queue = advancedBus . QueueDeclare (
166
177
conventions . RpcReturnQueueNamingConvention ( ) ,
@@ -174,15 +185,15 @@ protected virtual string SubscribeToResponse<TRequest, TResponse>()
174
185
queue ,
175
186
queue . Name ) ;
176
187
177
- advancedBus . Consume < TResponse > ( queue , ( message , messageReceivedInfo ) => Task . Factory . StartNew ( ( ) =>
188
+ var cancellation = advancedBus . Consume < TResponse > ( queue , ( message , messageReceivedInfo ) => Task . Factory . StartNew ( ( ) =>
178
189
{
179
190
ResponseAction responseAction ;
180
191
if ( responseActions . TryRemove ( message . Properties . CorrelationId , out responseAction ) )
181
192
{
182
193
responseAction . OnSuccess ( message ) ;
183
194
}
184
195
} ) ) ;
185
- responseQueues . TryAdd ( rpcKey , queue . Name ) ;
196
+ responseQueues . TryAdd ( rpcKey , new ResponseQueueWithCancellation { QueueName = queue . Name , Cancellation = cancellation } ) ;
186
197
return queue . Name ;
187
198
}
188
199
}
@@ -193,6 +204,12 @@ protected struct RpcKey
193
204
public Type Response ;
194
205
}
195
206
207
+ protected struct ResponseQueueWithCancellation
208
+ {
209
+ public string QueueName ;
210
+ public IDisposable Cancellation ;
211
+ }
212
+
196
213
protected class ResponseAction
197
214
{
198
215
public Action < object > OnSuccess { get ; set ; }
@@ -257,7 +274,11 @@ protected Task ExecuteResponder<TRequest, TResponse>(Func<TRequest, Task<TRespon
257
274
where TRequest : class
258
275
where TResponse : class
259
276
{
277
+ #if NETFX && ! NET46
260
278
var tcs = new TaskCompletionSource < object > ( ) ;
279
+ #else
280
+ var tcs = new TaskCompletionSource < object > ( TaskCreationOptions . RunContinuationsAsynchronously ) ;
281
+ #endif
261
282
262
283
try
263
284
{
@@ -344,4 +365,4 @@ private IExchange DeclareAndBindRpcExchange(string exchangeName, IQueue queue, s
344
365
return exchange ;
345
366
}
346
367
}
347
- }
368
+ }
0 commit comments