【问题标题】:MSMQ - ReceiveCompleted - Process Messages asyncMSMQ - ReceiveCompleted - 异步处理消息
【发布时间】:2017-02-12 03:05:31
【问题描述】:

我正在使用 BeginnReceive 方法和 ReceiveCompleted 事件处理程序来侦听和处理来自 MSMQ 的消息。

我已将 BeginReceive 方法放在 ReceiveCompleted 事件处理程序的开头。

看起来它在我的控制台应用程序中运行良好。 现在,消息是异步处理的。

问题: 关于线程安全,这是否安全?
我看到的所有示例都将 BeginReceive 调用置于已完成事件处理程序的末尾。所以我问自己把它放在完成的处理程序的最开始有什么问题吗?

private void InitializeQueue()
{
    try
    {
        _mq = MessageQueue.GetPrivateQueuesByMachine(_queueServerName).Where(qu => qu.Path == _queueAddress).FirstOrDefault();
        _mq.Formatter = new BinaryMessageFormatter();
        _mq.ReceiveCompleted += MessageReceiveCompleted;

    }
    catch (Exception ex)
    {
        Trace.WriteLine("Failed to initialize Queue!" + Environment.NewLine + " Error:" + Environment.NewLine + ex.Message);
        throw;
    }
}


async void MessageReceiveCompleted(object sender, ReceiveCompletedEventArgs e)
{
    _mq.BeginReceive();
    try
    {    
        await ProcessMessageAsync(e.Message);
    }
    catch (Exception ex)
    {
        Trace.WriteLine("Error occured during report fetching:" + Environment.NewLine + ex.Message);
        throw;
    }
}

【问题讨论】:

  • 代码中的多线程访问在哪里,以了解和衡量影响
  • BeginReceive 用于异步处理以在队列中有消息时引发 ReceiveCompleted 事件。在涉及异步问题时,我不是那么多才多艺..所以我最好在遇到麻烦之前问一下..
  • 如果订单很重要,我可以将 BeginReceive 放在最后并使用 Task.Run... 调用 ProcessMessageAsync...
  • 你的理解不正确,Async-Await依赖于基于硬件的并发机制IO完成端口。这没有任何软件线程,但仍然在后台并发。直到您创建 3 个或更多 Async 调用,await 为所有使用 Task.WhenAll 的调用,返回复合 Task,在执行开始后,它们将以并发模式执行。在您粘贴的代码中,我没有发现任何多线程问题,单个对象 mq,注册事件,发布通知,它同步执行 BeginReceive,然后在异步模式下等待 Web 服务调用
  • 另请注意,Web 服务是一个 IO 调用,通过 Task.Run 调用将没有什么用处,因为用于计算处理的线程只会等待 IO 调用返回。在您的完整代码 sn-p 中,我看不到多个线程,这可能会导致竞争条件或损坏等问题

标签: c# asynchronous async-await msmq


【解决方案1】:

是的,您使用 async/await 的方法将安全地处理线程。c# 使用这些关键字的异步方法会很小心。 更具体地说,我的答案是事件处理程序方法 messagereceived (方法名称应以 async 结尾)调用并等待异步方法,如果此方法内有任何阻塞工作,则线程将暂停在那里并进一步执行,直到其他工作完成和返回,就像在这种情况下 processmessage async 可能被阻塞并且可以进一步执行调用但我没有看到你利用它,因为在调用 processmessageasync 之后你没有做任何事情,所以如果你问线程将执行这个如果它是线程安全的,是的,但没有充分利用异步方法

【讨论】:

  • 你能解释一下这个答案是什么意思,以及它如何回答OP的问题
  • 请在您的答案中添加更多细节。说“是的,你的方法会奏效”只是一个评论。
  • BeginRecieve 异步侦听,每次有新消息到达时,都会调用完成的处理程序。例如,如果 15 条消息连续到达,它们都会在几秒钟内执行。问题是,它们是否都由工作负载之间共享的一个线程执行,看起来是这样..
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-19
  • 1970-01-01
相关资源
最近更新 更多