11using MerQure . Messages ;
22using MerQure . RbMQ . Content ;
3- using MerQure . RbMQ . Events ;
43using RabbitMQ . Client ;
54using RabbitMQ . Client . Events ;
65using System ;
76using System . Collections . Generic ;
87using System . Linq ;
98using System . Text ;
9+ using System . Threading ;
1010using System . Threading . Tasks ;
1111
1212namespace MerQure . RbMQ . Clients ;
@@ -17,33 +17,37 @@ class Consumer : RabbitMqClient, IConsumer
1717
1818 private AsyncEventingBasicConsumer _consumer ;
1919 private readonly ushort _prefetchCount ;
20- private readonly object _consumingLock ;
20+ private readonly SemaphoreSlim _consumingLock ;
2121
2222 public Consumer ( IChannel channel , string queueName , ushort prefetchCount )
2323 : base ( channel )
2424 {
2525 QueueName = queueName . ToLowerInvariant ( ) ;
2626 _prefetchCount = prefetchCount ;
27- _consumingLock = new object ( ) ;
27+ _consumingLock = new SemaphoreSlim ( 1 , 1 ) ;
2828 }
2929
30- public async Task ConsumeAsync ( EventHandler < IMessagingEvent > onMessageReceived )
30+ public async Task ConsumeAsync ( AsyncEventHandler < MessagingEvent > onMessageReceived )
3131 {
3232 await Channel . BasicQosAsync ( 0 , _prefetchCount , false ) ;
3333
3434 _consumer = new AsyncEventingBasicConsumer ( Channel ) ;
35- _consumer . ReceivedAsync += ( sender , args ) =>
35+ _consumer . ReceivedAsync += async ( sender , args ) =>
3636 {
3737 if ( onMessageReceived != null )
3838 {
39- lock ( _consumingLock )
39+ await _consumingLock . WaitAsync ( ) ;
40+ try
4041 {
4142 var message = ParseDeliveredMessage ( args ) ;
4243 var messageEventArgs = new MessagingEvent ( message , args . DeliveryTag . ToString ( ) ) ;
43- onMessageReceived ( sender , messageEventArgs ) ;
44+ await onMessageReceived ( sender , messageEventArgs ) ;
45+ }
46+ finally
47+ {
48+ _consumingLock . Release ( ) ;
4449 }
4550 }
46- return Task . CompletedTask ;
4751 } ;
4852
4953 await Channel . BasicConsumeAsync ( QueueName , false , _consumer ) ;
@@ -89,17 +93,18 @@ public async Task StopConsuming(AsyncEventHandler<ConsumerEventArgs> onConsumerS
8993 {
9094 if ( IsConsuming ( ) )
9195 {
92- lock ( _consumingLock )
96+ await _consumingLock . WaitAsync ( ) ;
97+ try
9398 {
9499 if ( onConsumerStopped != null )
95100 {
96- _consumer . UnregisteredAsync += ( sender , e ) =>
97- {
98- onConsumerStopped ( sender , e ) ;
99- return Task . CompletedTask ;
100- } ;
101+ _consumer . UnregisteredAsync += onConsumerStopped ;
101102 }
102103 }
104+ finally
105+ {
106+ _consumingLock . Release ( ) ;
107+ }
103108
104109 // Must be outside the lock to avoid deadlock
105110 foreach ( var tag in _consumer . ConsumerTags )
0 commit comments