0

I am receiving messages from MSMQ. An event is fired when a message is received, in some situations a delay be required before the event is fired. At the moment I have a Task.Delay to wait for the specified time before firing the event. I am wondering if anyone has a better solution or can see any problems in my current solution:

    private List<Task> _delayTasks = new List<Task>();

    private void PeekComplete(object sender, msmq.PeekCompletedEventArgs e)
    {
            //..code to get mesage off the queue...

            double delay = _messageTimeOut.TimeOutRequired(messageBody);

            if (delay > 0)
            {
                CreateDelayTask(delay, messageBody);
                WaitDelays();
            }
            else
            {
                _OnMessageReceived?.Invoke(messageBody);
                ProcessingCounter.Decrement();
            }

           GetNextMessage();

    }

    private void WaitDelays()
    {
        while (_delayTasks.Count > 0)
        {
            int index = -1;

            try
            {
                index = Task.WaitAny(_delayTasks.ToArray());
            }
            finally
            {
                if (index > -1)
                    _delayTasks.RemoveAt(index);
            }

        }
    }

    private void CreateDelayTask(double milliSecondsTimeOut, string messageBody)
    {
        var delay = (int)Math.Ceiling(milliSecondsTimeOut);

        var task = Task.Delay(delay).ContinueWith((antecedent) =>
         {
             try
             {
                 _OnMessageReceived?.Invoke(messageBody);
             }
             catch (Exception ex)
             {
                 _OnMessageReceivedError?.Invoke(ex, messageBody);
             }
             finally
             {
                 ProcessingCounter.Decrement();
             }
         });

        _delayTasks.Add(task);
    }
Andrew
  • 691
  • 6
  • 17
  • 1
    Can you not use `await Task.Delay(...)`? Your current code is blocking and that's a bad idea. Ideally you should post a [mcve] for us to work with - without one it is usually quite difficult to give a good answer. – Enigmativity Oct 25 '17 at 23:54
  • Thanks Enigmativity, what other information would be helpful for you? Also thanks for your answer. I am wondering what will happen if I use `await Task.Delay`, I will continue to receive messages from MSMQ, if there is 10 000 to receive, will this create 10 000 delay tasks? – Andrew Oct 25 '17 at 23:58
  • Thanks Enigmativity. Your solution works well because the code doesn't call the 'GetNextMessage' until after the delay (or await), so the tasks will not pile up as I was concerned about. – Andrew Oct 26 '17 at 00:44
  • What would be useful is a [mcve] - that means code that I can copy, paste, and run and see it work. Then I can offer working code in return. – Enigmativity Oct 26 '17 at 01:08
  • is your code just waiting to process the message before processing the next one? – Keith Nicholas Oct 26 '17 at 02:54
  • Hi Keith, yes delay by milliseconds. – Andrew Oct 26 '17 at 03:46

0 Answers0