【问题标题】:MSMQ in .NET: synchronous vs asynchronous? [closed].NET 中的 MSMQ:同步与异步? [关闭]
【发布时间】:2012-09-09 21:19:00
【问题描述】:

何时使用哪种方法?

如果同步是专用的单独线程,是否有任何理由使用异步方法?

【问题讨论】:

  • 我找到了类似的线程,但与 JAVA 相关......另外在这里:stackoverflow.com/questions/12458065/… 是我的另一个相关问题,更具体,但我想大致了解和了解何时以及哪种方法更好使用。

标签: c# .net msmq messaging


【解决方案1】:

您使用异步方法来防止阻塞调用线程。此外,最好使用这种方法,而不是创建自己的专用线程来使用同步方法。这是 .NET 通用建议,最好让 .NET 完成异步工作,而不是创建自己的专用线程。

编辑:Here is one question 您可能对 MSMQ 和 EndReceive 感兴趣,这是 .NET 中 MSMQ 异步模型的一部分。

【讨论】:

  • 谢谢...事件处理程序呢 - 它在哪里执行?在单独的线程/上下文中还是我理解错了?附言我也很高兴获得一些与主题相关的链接 - 一些案例研究或一般理论......
  • @ALZ - 在实际运行该方法的线程上调用事件处理程序。我会看看是否能找到针对这些主题的一些具体建议,但要记住一点:创建线程是一项相当重量级的操作,一般来说,最好使用内部使用优化线程池的 .NET 异步处理(或无论他们想出什么其他魔法;-)。
  • 如果该线程(实际运行该方法)正忙(进行一些操作和/或迭代)会发生什么?它是否被事件处理程序中断并阻塞直到事件处理程序完成?
  • 接下来我发现了与socket相关的:“在调用BeginReceive之前,你需要创建一个实现AsyncCallback委托的回调方法。这个回调方法在一个单独的线程中执行并且是BeginReceive 返回后由系统调用。”接下来在 MSQM 上:“因为 BeginReceive 是异步的,所以您可以调用它来从队列中接收消息,而不会阻塞当前的执行线程。”是一样的吗?
  • @ALZ - 很好地发现了这一点,但我不知道这种行为是否得到保证。
【解决方案2】:

我建议在使用 MSMQ 时使用异步方法。

MSMQ 的主要目的之一是提供一种在解耦系统之间发送数据的解决方案。换句话说,理想情况下,发布者和订阅者不应该相互了解任何信息,只要他们知道如何处理消息内容即可。

这包括发送者无需担心接收者处理发送的消息的时间。它可以立即处理,也可以在接收者队列中已经堆积了几千条其他消息之后处理。

或者考虑一个离线数小时甚至数天的接收器。使用事务队列时,即使接收者重新联机,您的消息也会立即传递,但您是否希望同步等待这么长时间? :-)

与往常一样,这取决于您想做什么

如果您想保证消息按特定顺序处理,使用同步方法可能会有所帮助。但我想还有更多的情况是不关心,或者太复杂而无法做出任何保证。

一些例子让我的意思更清楚:

  • 想象一下一个涉及负载平衡器/调度器的架构。当该平衡器将接收到的消息传播到多个服务或线程时,您不能依赖于顺序和时间等方面。恕我直言,您不想同步执行此操作。

  • 另一种常见的做法是让多个订阅者到单个发布者。一个简单的例子可能是想要将最新的聊天消息发送给几百个聊天客户端的聊天服务器。同样,您不希望同步执行此操作。

回到这个问题,您不会放弃任何东西从一开始就使用异步。相反,您实现它的使用越解耦,您就会获得灵活性可扩展性

【讨论】:

  • 感谢您的回复,但是,无论如何,我对此有一些误解: - 发送始终是同步的,不是吗?我感兴趣的是接收,在我的具体情况下,我只有两个系统:一个主要发送,另一个主要接收。在这种情况下,即使我将使用异步侦听,这里是否存在消息将不会按照它们在 MSMQ 队列中排队的顺序进行处理的可能性?
  • @ALZ:当然,消息本身是按照它们到达队列的顺序进行处理的。但是,由于例如,它们的发送顺序不一定相同。网络负载,多线程发布者。或者,如果多个不同的进程写入同一个队列,则消息会连续混淆。有多个线程监听同一个队列或多次调用BeginReceive() 方法是一种常见的情况,这将产生对队列的多个异步访问。在这些情况下,您无法预测何时处理哪条消息。
【解决方案3】:

之后……

Async 读取不持有读取线程。它注册一个回调,当一条消息被完全读取时,它带着这条消息返回给原来的被调用者。如果你需要你的线程做一些其他的工作,那就太好了。

我实际发现的是,sync 的读取速度是异步的两倍。因为不涉及回调并且线程开销可能更少,所以单个线程从队列中读取的消息数量是双倍的。

我建议在您的平台上进行测量,而不是盲目地遵循 async-await 模式(这在大多数其他情况下非常好)

【讨论】:

    猜你喜欢
    • 2011-07-26
    • 1970-01-01
    • 1970-01-01
    • 2014-01-13
    • 2014-01-05
    • 1970-01-01
    • 2015-02-23
    • 2012-11-03
    • 1970-01-01
    相关资源
    最近更新 更多