How can I read messages from a queue in parallel?

前端 未结 5 1405
孤独总比滥情好
孤独总比滥情好 2021-01-03 12:36

Situation

We have one message queue. We would like to process messages in parallel and limit the number of simultaneously processed messages.

Our trial code

5条回答
  •  旧巷少年郎
    2021-01-03 13:09

    My colleague came up with the solution below. This solution works, but I'll let this code be reviewed on Code Review.

    Based on answers given and some research of our own, we've come to a solution. We're using a SemaphoreSlim to limit our number of parallel Tasks.

    static string queue = @".\Private$\concurrenttest";
    
    private static async Task Process(CancellationToken token)
    {
        MessageQueue msMq = new MessageQueue(queue);
        msMq.Formatter = new XmlMessageFormatter(new Type[] { typeof(Command1) });
        SemaphoreSlim s = new SemaphoreSlim(15, 15);
    
        while (true)
        {
            await s.WaitAsync();
            await PeekAsync(msMq);
            Command1 message = await ReceiveAsync(msMq);
            Task.Run(async () =>
            {
                try
                {
                    await HandleMessage(message);
                }
                catch (Exception)
                {
                    // Exception handling
                }
                s.Release();
            });
        }
    }
    
    private static Task HandleMessage(Command1 message)
    {
        Console.WriteLine("id: " + message.id + ", name: " + message.name);
        Thread.Sleep(1000);
        return Task.FromResult(1);
    }
    
    private static Task PeekAsync(MessageQueue msMq)
    {
        return Task.Factory.FromAsync(msMq.BeginPeek(), msMq.EndPeek);
    }
    
    public class Command1
    {
        public int id { get; set; }
        public string name { get; set; }
    }
    
    private static async Task ReceiveAsync(MessageQueue msMq)
    {
        var receiveAsync = await Task.Factory.FromAsync(msMq.BeginReceive(), msMq.EndPeek);
        return (Command1)receiveAsync.Body;
    }
    

提交回复
热议问题