3
3
using System . Collections . Generic ;
4
4
using System . Linq ;
5
5
using System . Threading ;
6
+ using System . Threading . Channels ;
6
7
using System . Threading . Tasks ;
7
8
using RabbitMQ . Client ;
8
9
using RabbitMQ . Client . Events ;
@@ -14,7 +15,11 @@ internal sealed class FakeModel : IModel
14
15
{
15
16
private readonly ConcurrentDictionary < ulong , RabbitMessage > workingMessages = new ConcurrentDictionary < ulong , RabbitMessage > ( ) ;
16
17
private readonly ConcurrentDictionary < string , IBasicConsumer > consumers = new ConcurrentDictionary < string , IBasicConsumer > ( ) ;
17
- private readonly BlockingCollection < Action > deliveries = new BlockingCollection < Action > ( ) ;
18
+ private readonly Channel < Action > deliveries = Channel . CreateUnbounded < Action > ( new UnboundedChannelOptions
19
+ {
20
+ SingleReader = true ,
21
+ SingleWriter = false ,
22
+ } ) ;
18
23
private readonly RabbitServer server ;
19
24
private readonly Task deliveriesTask ;
20
25
private long lastDeliveryTag ;
@@ -122,9 +127,9 @@ void notifyConsumerOfMessage(RabbitMessage message)
122
127
_ = consumers . AddOrUpdate ( consumerTag , consumer , updateFunction ) ;
123
128
124
129
foreach ( var message in queueInstance . Messages )
125
- deliveries . Add ( ( ) => notifyConsumerOfMessage ( message ) ) ;
130
+ _ = deliveries . Writer . TryWrite ( ( ) => notifyConsumerOfMessage ( message ) ) ;
126
131
queueInstance . MessagePublished += ( sender , message ) =>
127
- deliveries . Add ( ( ) => notifyConsumerOfMessage ( message ) ) ;
132
+ _ = deliveries . Writer . TryWrite ( ( ) => notifyConsumerOfMessage ( message ) ) ;
128
133
129
134
if ( consumer is IAsyncBasicConsumer asyncBasicConsumer )
130
135
asyncBasicConsumer . HandleBasicConsumeOk ( consumerTag ) . GetAwaiter ( ) . GetResult ( ) ;
@@ -257,7 +262,7 @@ private void Close(ushort replyCode, string replyText, bool abort)
257
262
try
258
263
{
259
264
CloseReason = reason ;
260
- deliveries . CompleteAdding ( ) ;
265
+ deliveries . Writer . TryComplete ( ) ;
261
266
deliveriesTask . Wait ( ) ;
262
267
ModelShutdown ? . Invoke ( this , reason ) ;
263
268
}
@@ -282,7 +287,6 @@ public void ConfirmSelect()
282
287
public void Dispose ( )
283
288
{
284
289
if ( IsOpen ) Abort ( ) ;
285
- deliveries . Dispose ( ) ;
286
290
}
287
291
288
292
public void ExchangeBind ( string destination , string source , string routingKey , IDictionary < string , object > arguments )
@@ -471,20 +475,25 @@ public bool WaitForConfirms(TimeSpan timeout, out bool timedOut)
471
475
/// semantics as running delivery callbacks synchronously can cause deadlocks in
472
476
/// code under test.
473
477
/// </summary>
474
- private void HandleDeliveries ( )
478
+ private async Task HandleDeliveries ( )
475
479
{
476
480
try
477
481
{
478
- foreach ( var delivery in deliveries . GetConsumingEnumerable ( ) )
479
- try
480
- {
481
- delivery ( ) ;
482
- }
483
- catch ( Exception ex )
482
+ while ( await deliveries . Reader . WaitToReadAsync ( ) . ConfigureAwait ( false ) )
483
+ {
484
+ while ( deliveries . Reader . TryRead ( out var delivery ) )
484
485
{
485
- var callbackArgs = CallbackExceptionEventArgs . Build ( ex , "" ) ;
486
- CallbackException ( this , callbackArgs ) ;
486
+ try
487
+ {
488
+ delivery ( ) ;
489
+ }
490
+ catch ( Exception ex )
491
+ {
492
+ var callbackArgs = CallbackExceptionEventArgs . Build ( ex , "" ) ;
493
+ CallbackException ( this , callbackArgs ) ;
494
+ }
487
495
}
496
+ }
488
497
}
489
498
catch
490
499
{
0 commit comments