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));
            }
        }
    }
}
3
  • As a side comment: look at how tcp works. It may be useful for this scenario.
    – Pieter B
    Commented Aug 9, 2019 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. Commented Aug 9, 2019 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
    Commented Aug 10, 2019 at 11:06

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.