/// <summary>
        /// Send and receive serial communication asynchronously.
        /// </summary>
        /// <param name="cmd">Send command</param>
        /// <remarks>
        /// [Note]
        /// If you let the UI thread process while receiving data, data is likely to be missed.
        /// Data is sent and received in order using the command response method.
        ///    1.Send command from form
        /// -> 2.Send and receive command in thread
        /// -> 3.Write received data on form
        /// </remarks>
        async private void AsyncSerialPort(byte cmd)
        {
            // Clear the log area every 1000 times.
            if (this._normalCount % 1000 == 0)
            {
                this.txtLog.Clear();
            }

            // Get send command from definition list.
            this._lastSendCommandID = cmd;
            TOFCommand command = this.GetCommand(cmd);

            this._serialPort.ReceivedDataLength = 0;

            // Write send command information to log area.
            this.txtLog.AppendText(string.Format("{0}  {1}  {2}  {3}\r\n"
                                                 , DateTime.Now.ToString("HH:mm:ss.fff")
                                                 , command.SendDataLength.ToString("D7")
                                                 , "Send   "
                                                 , BitConverter.ToString(command.SendData)));
            this.txtLog.ScrollToCaret();

            // Send send command to serial port asynchronously.
            await Task.Run(() => this._serialPort.SendReceive(command));

            // When called back, write the received data.
            this.CallbackSerialPort();
        }
 /// <summary>
 /// Send Command And Wait for Receive Response
 /// </summary>
 /// <param name="command">Command class object</param>
 public void SendReceive(TOFCommand command)
 {
     // Set command from parameter.
     this._command = command;
     // Set the flag to True to start sending and receiving.
     this._isSendingReceiving = true;
     // Wait until sending and receiving stops.
     while (this._isSendingReceiving)
     {
         Thread.Yield();
     }
 }
        /// <summary>
        /// Callback processing after receiving data.
        /// </summary>
        /// <remarks>
        /// </remarks>
        private void CallbackSerialPort()
        {
            byte[] data    = this._serialPort.ReceiveDataBuffer;
            int    length  = this._serialPort.ReceivedDataLength;
            bool   isError = this._serialPort.IsError;

            try
            {
                if (6 <= length && data[0] == 0xFE)
                {
                    // When the synchronization code is 0xFE and the received data length is 6 or more.
                    int dataLength = (data[2] << 24) + (data[3] << 16) + (data[4] << 8) + data[5];
                    if (length == dataLength + 6)
                    {
                        // When all data can be received,
                        // Write received data information to log area.
                        this._normalCount++;
                        this.txtResult.Text = string.Format("Nromal count:{0}. Error count:{1}.", this._normalCount.ToString(), this._errorCount.ToString());
                        this.txtLog.AppendText(string.Format("{0}  {1}  {2}  {3}\r\n"
                                                             , DateTime.Now.ToString("HH:mm:ss.fff")
                                                             , length.ToString("D7")
                                                             , "Receive"
                                                             , BitConverter.ToString(data, 0, 20 <= length ? 20 : length)));
                        this.txtLog.ScrollToCaret();

                        // If Output CSV is TRUE, CSV output.
                        if (this._lastSendCommandID == 0x82 && this.chkOutputCSV.Checked)
                        {
                            // Get command definition.
                            TOFCommand command = this.GetCommand(this._lastSendCommandID);
                            // Extract get result data from the receive buffer.
                            byte[] resultData = new byte[command.ReceiveDataLength];
                            Buffer.BlockCopy(data, 0, resultData, 0, length);
                            // CSV output.
                            this.OutputCsv(resultData);
                        }

                        // If Repeat is TRUE, Send Get result command.
                        if (this.chkRepeat.Checked)
                        {
                            this.AsyncSerialPort(this._lastSendCommandID);
                            return;
                        }
                    }
                    else
                    {
                        // When some data could not be received,
                        // Write received data information to log area.
                        this._errorCount++;
                        this.txtLog.AppendText(string.Format("Failed to receive data. The received data length is {0} bytes.\r\n"
                                                             , length));
                        this.txtLog.ScrollToCaret();

                        // If Repeat is TRUE, Send Get result command.
                        if (this.chkRepeat.Checked)
                        {
                            this.AsyncSerialPort(this._lastSendCommandID);
                            return;
                        }
                    }
                }
                else
                {
                    // When some data could not be received,
                    // Write received data information to log area.
                    this._errorCount++;
                    if (isError)
                    {
                        // When some data could not be received,
                        // Write received data information to log area.
                        this.txtLog.AppendText(string.Format("Failed to send data.\r\n"));
                    }
                    else
                    {
                        // When some data could not be received,
                        // Write received data information to log area.
                        this.txtLog.AppendText(string.Format("Failed to receive data.\r\n"));
                    }
                    this.txtLog.ScrollToCaret();

                    // If Repeat is TRUE, Send Get result command.
                    if (this.chkRepeat.Checked)
                    {
                        this.AsyncSerialPort(this._lastSendCommandID);
                        return;
                    }
                }
            }
            catch (ObjectDisposedException)
            {
                // Do nothing until the object is destroyed.
            }
        }