1

When and which approach to use?

Is there any reason to use asynchronous methods, if for synchronous is dedicated separate thread?

Kiquenet
  • 14,494
  • 35
  • 148
  • 243
ALZ
  • 1,997
  • 2
  • 27
  • 44
  • I found similar thread, but related to JAVA... Also here: http://stackoverflow.com/questions/12458065/msmq-what-is-better-approach-to-listen-in-multithreadin-service is one my another related question, more specific, BUT I want to know and understand generally when and which approach is better to use. – ALZ Sep 17 '12 at 16:00

3 Answers3

2

You use the asynchronous method to prevent blocking the calling thread. Also, it is preferable to use this approach as opposed to creating your own dedicated thread that will use the sync method. This is .NET general-purpose advice, better to let .NET do the async work, than to create your own dedicated threads.

EDIT: Here is one question that might be of interest to you regarding MSMQ and EndReceive, which is part of the asynchronous model for MSMQ in .NET.

Community
  • 1
  • 1
Chris O
  • 5,017
  • 3
  • 35
  • 42
  • thanks... what about event handler - where does it execute? In separate thread/context or I am understanding it wrong? P.S. I will also be pleased to get some links related to topic - some case study or general theory... – ALZ Sep 17 '12 at 16:07
  • 1
    @ALZ - The event handler is called on the thread that actually ran the method. I'll see if I can find some specific advice for these topics but one point to keep in mind: creating a thread is a rather heavyweight operation, in general it is better to use .NET async processing which internally uses optimized thread pools (or whatever other magic they come up with ;-). – Chris O Sep 17 '12 at 16:46
  • And what happen if that thread (that actually ran the method) is busy (making some operation and or iteration)? Is it interrupted by event handler and blocked until event handler is finished? – ALZ Sep 17 '12 at 16:50
  • Related to socket i found next: "Before calling BeginReceive, you need to create a callback method that implements the AsyncCallback delegate. **This callback method executes in a separate thread** and is called by the system after BeginReceive returns." On MSQM next: "Because BeginReceive is asynchronous, you can call it to receive a message from the queue without blocking the current thread of execution." Is it THE SAME? – ALZ Sep 17 '12 at 21:01
  • OK, finally i cheeked it by printing ThreadID - event handler are executed in separate thread, other then thread where listening was started (1st BeginReceive). – ALZ Sep 18 '12 at 06:39
  • 1
    @ALZ - good work finding that out, but I don't know if that behavior is guaranteed though. – Chris O Sep 18 '12 at 12:03
0

I suggest to use the asychronous approach when using the MSMQ.

One of the main purposes of MSMQ is to provide a solution to send data between decoupled systems. In other words, ideally both publisher and subscriber should not know anything about each other, as long as they know how to handle the message contents.

This includes that the sender should not need to worry about whenever the receiver handles the sent message. It could be handled right away or after a few thousand other messages that are already piled in the receiver's queue.

Or think about a receiver that is offline for hours or even days. When using transactional queues, your messages would even then be delivered as soon as the receivers comes back online, but would you want to wait synchronously for so long? :-)

As always, it depends on what you want to do.

If you want to, say, guarantee that the messages are handled in a certain order, using a synchronous approach might be helpful. But I guess that there are more situation in which do do not care, or that are too complex to make any guarantees.

Some examples to make clearer what I mean:

  • Just imagine an architecture that involves a load balancer/dispatcher. When that balancer spreads the received messages over multiple services or threads, you cannot rely on aspects like order and timing. IMHO, you would not want to do this synchronously.

  • Another common practice is having multiple subscribers to a single publisher. An easy example could be a chat server that wants to send the latest chat message to a couple of hundred chat clients. Again, you would not want to do this synchronously.

Coming back to the question, you are not giving away anything to use async right from the begining. Instead you gain flexibility and scalability the more decoupled you implement its usage.

Jens H
  • 4,590
  • 2
  • 25
  • 35
  • thanks for response, but, anyway, I have some misunderstandings related to it: - Sending is always synchronous, isn't it? In my interest is Receiving, and in my concrete case, i have only 2 systems: one mostly sending, another mostly receiving. In this case, even if I'll use asynchronous listening, does exist here probability that messages will be processed not in that order, in which they were queued in MSMQ Queue? – ALZ Sep 20 '12 at 14:30
  • 1
    @ALZ: Of course the messages themselves are processed in the order in which they arrive in the queue. BUT it is not necessarly the same order in which they were send, due to e.g. network load, a multi-threaded publisher. OR if more multiple different processes write into the same queue the messages get consecutively mixed up. It is a common scenario to also have multiple threads listening to the same queue or calling the `BeginReceive()` method multiple times, which would spawn multiple async accesses to the queue. In these cases you could not predict when which message is handled. – Jens H Sep 20 '12 at 14:59
0

Sometime after...

Async read does not hold a reading thread. It registers a callback and when a message is fully read, it returns to the original callee with this message. This is wonderful if you need your thread to do some other work.

What I actually found, was that a sync read to be twice as fast as async. Because there is no callbacks involved and possibly fewer threading overhead, a single thread was reading double the number of messages from a queue.

I'd recommend to measure this on your platform, instead of blindly follow async-await pattern (which is really good in most other cases)

oleksii
  • 35,458
  • 16
  • 93
  • 163