/// <summary> Sends a command. /// If no command acknowledge is requested, the command will be send asynchronously: it will be put on the top of the send queue /// If a command acknowledge is requested, the command will be send synchronously: the program will block until the acknowledge command /// has been received or the timeout has expired. /// Based on ClearQueueState, the send- and receive-queues are left intact or are cleared</summary> /// <param name="sendCommand"> The command to sent. </param> /// <param name="clearQueueState"> Property to optionally clear the send and receive queues</param> /// <returns> A received command. The received command will only be valid if the ReqAc of the command is true. </returns> public ReceivedCommand SendCommand(SendCommand sendCommand, ClearQueue clearQueueState) { //_sendCommandLogger.LogLine(CommandToString(sendCommand) + _commandSeparator); if (clearQueueState == ClearQueue.ClearReceivedQueue || clearQueueState == ClearQueue.ClearSendAndReceivedQueue) { // Clear receive queue _receiveCommandQueue.Clear(); } if (clearQueueState == ClearQueue.ClearSendQueue || clearQueueState == ClearQueue.ClearSendAndReceivedQueue) { // Clear send queue _sendCommandQueue.Clear(); } if (sendCommand.ReqAc) { // Directly call execute command return(ExecuteSendCommand(sendCommand, clearQueueState)); } // Put command at top of command queue _sendCommandQueue.SendCommand(sendCommand); return(new ReceivedCommand()); }
/// <summary> Sends a command. /// If no command acknowledge is requested, the command will be send asynchronously: it will be put on the top of the send queue /// If a command acknowledge is requested, the command will be send synchronously: the program will block until the acknowledge command /// has been received or the timeout has expired. /// Based on ClearQueueState, the send- and receive-queues are left intact or are cleared</summary> /// <param name="sendCommand"> The command to sent. </param> /// <param name="sendQueueState"> Property to optionally clear/wait the send queue</param> /// <param name="receiveQueueState"> Property to optionally clear/wait the send queue</param> /// <param name="useQueue"> Property to optionally bypass the queue</param> /// <returns> A received command. The received command will only be valid if the ReqAc of the command is true. </returns> public ReceivedCommand SendCommand(SendCommand sendCommand, SendQueue sendQueueState, ReceiveQueue receiveQueueState, UseQueue useQueue) { var synchronizedSend = (sendCommand.ReqAc || useQueue == UseQueue.BypassQueue); // When waiting for an acknowledge, it is typically best to wait for the ReceiveQueue to be empty // This is thus the default state if (sendCommand.ReqAc && receiveQueueState == ReceiveQueue.Default) { receiveQueueState = ReceiveQueue.WaitForEmptyQueue; } if (sendQueueState == SendQueue.ClearQueue) { // Clear receive queue _receiveCommandQueue.Clear(); } if (receiveQueueState == ReceiveQueue.ClearQueue) { // Clear send queue _sendCommandQueue.Clear(); } // If synchronized sending, the only way to get command at end of queue is by waiting if (sendQueueState == SendQueue.WaitForEmptyQueue || (synchronizedSend && sendQueueState == SendQueue.AtEndQueue) ) { SpinWait.SpinUntil(() => _sendCommandQueue.IsEmpty); } if (receiveQueueState == ReceiveQueue.WaitForEmptyQueue) { SpinWait.SpinUntil(() => _receiveCommandQueue.IsEmpty); } if (synchronizedSend) { return(SendCommandSync(sendCommand, sendQueueState)); } if (sendQueueState != SendQueue.AtEndQueue) { // Put command at top of command queue _sendCommandQueue.SendCommand(sendCommand); } else { // Put command at bottom of command queue _sendCommandQueue.QueueCommand(sendCommand); } return(new ReceivedCommand { CommunicationManager = _communicationManager }); }
/// <summary> Sends a command. /// If no command acknowledge is requested, the command will be send asynchronously: it will be put on the top of the send queue /// If a command acknowledge is requested, the command will be send synchronously: the program will block until the acknowledge command /// has been received or the timeout has expired. /// Based on ClearQueueState, the send- and receive-queues are left intact or are cleared</summary> /// <param name="sendCommand"> The command to sent. </param> /// <param name="sendQueueState"> Property to optionally clear/wait the send queue</param> /// <param name="receiveQueueState"> Property to optionally clear/wait the send queue</param> /// <param name="useQueue"> Property to optionally bypass the queue</param> /// <returns> A received command. The received command will only be valid if the ReqAc of the command is true. </returns> public ReceivedCommand SendCommand(SendCommand sendCommand, SendQueue sendQueueState, ReceiveQueue receiveQueueState, UseQueue useQueue) { //_sendCommandLogger.LogLine(sendCommand.CommandString()); var synchronizedSend = (sendCommand.ReqAc || useQueue == UseQueue.BypassQueue); if (sendQueueState == SendQueue.ClearQueue) { // Clear receive queue _receiveCommandQueue.Clear(); } if (receiveQueueState == ReceiveQueue.ClearQueue) { // Clear send queue _sendCommandQueue.Clear(); } // If synchronized sending, the only way to get command at end of queue is by waiting if (sendQueueState == SendQueue.WaitForEmptyQueue || (synchronizedSend && sendQueueState == SendQueue.AtEndQueue) ) { while (_sendCommandQueue.Count > 0) { Thread.Sleep(1); } } if (receiveQueueState == ReceiveQueue.WaitForEmptyQueue) { while (_receiveCommandQueue.Count > 0) { Thread.Sleep(1); } } if (synchronizedSend) { return(SendCommandSync(sendCommand, sendQueueState)); } if (sendQueueState != SendQueue.AtEndQueue) { // Put command at top of command queue _sendCommandQueue.SendCommand(sendCommand); } else { // Put command at bottom of command queue _sendCommandQueue.QueueCommand(sendCommand); } return(new ReceivedCommand()); }