0

I have a simplified producer/consumer pattern implemented below. The code outputs:

"A"

1 second delay

"B"

1 second delay

"A"

1 second delay

"B"

...

What approach can I take here to get rid of the 1-second delay between different letters?

What I'm looking for is something like

"A"

"B"

1 second delay

"A"

"B"

...

It's important, that clients A and B receive the messages in the order the messages were queued in, but I do not want other clients to be blocked while processing for one client takes a really long time. Using two BlockingCollections and two consumer threads is not an option, because the user count is dynamic.

using System;
using System.Collections.Concurrent;
using System.Threading.Tasks;

namespace ConsumerProducer
{
    public enum ClientId
    {
        A,
        B
    }

    class WebSocketMessage
    {
        public ClientId ClientId { get; }

        public WebSocketMessage(ClientId clientId)
        {
            ClientId = clientId;
        }

        public async Task LongRunningSend()
        {
            Console.WriteLine(ClientId);
            await Task.Delay(TimeSpan.FromSeconds(1));
        }
    }

    class Program
    {
        public static BlockingCollection<WebSocketMessage> Messages = new BlockingCollection<WebSocketMessage>();

        static async Task Main(string[] args)
        {
            var consumer = Task.Run(async () =>
            {
                foreach (var message in Messages.GetConsumingEnumerable())
                {
                    await message.LongRunningSend();
                }
            });

            ClientId clientId = ClientId.B;
            while (true)
            {
                // Flip between A and B
                clientId = clientId == ClientId.A ? ClientId.B : ClientId.A;

                Messages.Add(new WebSocketMessage(clientId));

                await Task.Delay(TimeSpan.FromMilliseconds(100));
            }
        }
    }
}
  • As a side comment: look at how tcp works. It may be useful for this scenario. – Pieter B Aug 9 at 19:50
  • 3
    Add a "sequence number" or time stamp to your messages and buffer them in the receiver. This will allow you to reorder them into the proper sequence. – Robert Harvey Aug 9 at 19:57
  • Are these all running in a process with multiple threads? Can B see data that’s not meant for it while ignoring it? (Is data confident, though running in the same process defeats the purpose anyway.) Are those consumers long-running, always waiting for job? Or are they created on-demand? – Shane Hsu Aug 10 at 11:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.