Click or drag to resize

IncomingMessageManagerTTransaction Method

Sends a (pre-prepared) request and (optionally) waits for a response (synchronously or asynchronously).

Namespace:  Demo3D.Net
Assembly:  Demo3D.IO (in Demo3D.IO.dll) Version: 11.0.0.7658
Syntax
C#
public void Transaction(
	SendMessageDelegate sendMessage,
	IncomingMessageManagerTMessageHandler response,
	bool waitForResponse,
	int waitTimeoutMs,
	CallbackContext callbackContext = CallbackContext.CallerContext
)

Parameters

sendMessage
Type: Demo3D.NetSendMessageDelegate
A method for sending the initial request message.
response
Type: Demo3D.NetIncomingMessageManagerTMessageHandler
A handler for receiving the response (or null).
waitForResponse
Type: SystemBoolean
True to wait for and handle the response before returning. Otherwise the response is handled asynchronously in a separate thread.
waitTimeoutMs
Type: SystemInt32
How long to wait for the response (in milliseconds).
callbackContext (Optional)
Type: Demo3D.NetCallbackContext
Defines the context in which the message handler should be called.
Remarks

Exceptions:

This method may throw exceptions under different circumstances, depending on the configuration and the parameters passed to this call and to previous calls. If a handler throws an exception then the exception may be reported here. But if (for example) waitForResponse is false then the exception may be reported in the next call to this method, even though it does not relate to that transaction.

Best practice is for a handler not to throw exceptions, but rather to catch and handle the exceptions itself.

Timeouts:

It may still be necessary to pass a non-zero timeout in waitTimeoutMs even if waitForResponse is false. Although waitForResponse false implies that this method should not wait, and therefore a timeout is not required, there are circumstances when it will wait.

Depending on the configuration this method may be subject to flow control. For example if the configuration is RespondBehind, then we can't send this request until we've received the reply to the previous request, and this call will need to wait for that reply before it can send.

CallbackContext:

If this method is called with callbackContext set to CallerContext, then the handler will be called in the same synchronization context (thread) as this call. However, if waitForResponse is false, then the handler will need to be posted back to this thread at a later time (when the response arrives).

For synchronization contexts that only have one thread (eg the GUI thread, or the Demo3D model thread), then it's essential that you don't allow the thread to become blocked (otherwise the handler can't be processed). That includes not calling this blocking method (use TransactionAsync instead).

So for example code such as the following that sends out two packets without waiting for responses:

packetManager.Transaction(sendPacket1, responseHandler, false, 1000, CallbackContext.CallerContext);
packetManager.Transaction(sendPacket2, resposseHandler, false, 1000, CallbackContext.CallerContext);
If the the second call for packet 2 is issued before the response is received from the peer for the first packet, it'll hang and then timeout with a "Timeout waiting for message..." error - even though the peer does respond. Although the response is received from the peer for packet 1, it can't be processed because the thread that's required to process the first response is currently busy attempting to send the second request. It can't send the second request because RespondBehind dictates that it must wait until a response is received for the first request.

Best practice is to use TransactionAsync where possible. It's a mistake to call blocking methods in Demo3D scripting.

See Also