The message doesn't have to be dispatched immediately after sending, it can be delivered at a later time if necessary.
HandleCurrentMessageLater() method was primarily used to defer messages when using Versions 2.x and below, before the Defer functionality was introduced in Versions 3 and above. While this API is still supported in Versions 6 and below, there are significant caveats in using this API.
- Calling this method would create a copy of the message that has the same identifier, header, and body. This message would then be put at the end of the queue. The endpoint will eventually pick up this message once all the other messages in its queue have been processed. To make this work, the message pipeline will not abort which means any business transaction that's part of calling this method will also get committed.
- If the endpoint's queue is empty, or the condition to put the message back into the queue is incorrect, the message goes back into the queue immediately causing the endpoint to process the same message without any delay. This behavior can cause an endless loop which will manifest itself as a high system resource utilization by the endpoint.
bus.Defer(...) the handling of the message is deferred by certain amount of time. After that time the message is passed to be handled by the same endpoint. Semantically
bus.Defer(...) is equivalent to calling
bus.SendLocal(...) after time condition is met. See also sending local.
Using this mechanism delayed delivery can be achieved by calling
bus.Defer(...) which can be seen in Delayed Delivery Sample.
Deferwill also change the message's reply-to address to the endpoint deferring the message. Calling
Replyon a deferred message will send the reply to itself.
Delays delivery of a message for a specified duration.
bus.Defer(TimeSpan.FromMinutes(30), new MessageToBeSentLater());
Delays delivery of a message until a specified point in time.
bus.Defer(new DateTime(2016, 12, 25), new MessageToBeSentLater());
Delayed delivery of messages is supported when the one following requirements are met:
- The transport supports delayed delivery natively.
- The Timeout Manager feature is enabled and the endpoint is not a send-only endpoint.
When deferring a message, it is sent to the Timeout Manager requesting it to deliver the message at a later time or deferred by using the transports native capability to defer messages.
To enable the Timeout Manager, use following API:
NServiceBus provides delayed deliver feature for transports that don't have native support for delayed message delivery, i.e. for MSMQ and SQL Server transports. Transports that support delayed message delivery natively don't require persistence. To learn more about NServiceBus delayed message store refer to the Timeout Manager article.