1

I have two consumer on different queues in C# using RabbitMQ dot net library.

What i want:

Because of some business logic, I have to wait for some time in one consumer so i have used Thread.Sleep() for that purpose

Problem

if I use Thread.Sleep in one event the second thread is also not paused

My code:

consumer.Received += (model, ea) =>
{
    try
    {
        DRModel drModel = JsonConvert.DeserializeObject<DRModel>(Encoding.UTF8.GetString(ea.Body));
        RMQReturnType type = ProcessSubmitSMS(drModel);
        if (type == RMQReturnType.ACK)
            channel.BasicAck(ea.DeliveryTag, false);
        else
        { 
            channel.BasicNack(ea.DeliveryTag, false, true);
            Thread.Sleep(300000); // <=== SLEEP
        }
    }
    catch (Exception ex)
    {
        channel.BasicNack(ea.DeliveryTag, false, true);
        WriteLog(ControlChoice.ListError, "Exception: " + ex.Message + " | Stack Trace: " + ex.StackTrace.ToString() + " | [Consumer Event]");
    }
};


Bizhan
  • 16,157
  • 9
  • 63
  • 101
Usman Asif
  • 320
  • 2
  • 12

2 Answers2

0

It seems it is a good case for Mutex class, what you need is a conditional sleep in multithreading. Don't know exactly the logic that you need, but thy something like the code below:

public class Consumer
{
    public event EventHandler Received;

    public virtual void OnReceived()
    {
        Received?.Invoke(this, EventArgs.Empty);
    }
}

class Program
{
    static void Main(string[] args)
    {
        var mutex = new Mutex();

        var consumer =  new Consumer();

        consumer.Received += (model, ea) =>
        {
            try
            {
                mutex.WaitOne();
                var id = Guid.NewGuid().ToString();
                Console.WriteLine($"Start mutex {id}");
                Console.WriteLine($"Mutex finished {id}");
                Console.WriteLine($"Start sleep {id}");
                if ( new Random().Next(10000)  % 2 == 0) // randomly sleep, that your condition
                {
                    Thread.Sleep(3000); // <=== SLEEP
                }
                Console.WriteLine($"Sleep finished {id}");
            }
            catch (Exception ex)
            {
                mutex.ReleaseMutex(); // this is where you release, if something goes wrong
            }
            finally
            {
                mutex.ReleaseMutex();// always release it
            }
        };


        Parallel.For(0, 10, t =>   //running 10 threads in parallel and stops all if the condition is true
        {
            consumer.OnReceived();
        });

        Console.ReadLine();
    }

}

}

Elder Santos
  • 309
  • 2
  • 11
  • as per my understanding Thread.Sleep() sleep currrent thread and in my case it should be sleep current event why it does sleep other event. – Usman Asif Jan 02 '20 at 15:06
  • Mutex will work, you just need to start it at the top of your code, please check the code sample I edited. It will stop if the condition is true – Elder Santos Jan 03 '20 at 18:03
0

there is some logical error in my code whcih i understand. In rabbitmq i have created two consumer events on two different channels so i thought it will not be shared here i was wrong a connection was shared b/w channels so i explicly defin two connection for that. as i understand consumer block channel and channel block connection and connection is same in both events.

Usman Asif
  • 320
  • 2
  • 12