Пример #1
0
        /// <summary>
        /// Sends ZigBeeCommand command and uses the ZigBeeTransactionMatcher to match the response.
        /// The task will be timed out if there is no response.
        ///
        /// @param command the ZigBeeCommand
        /// @param responseMatcher the ZigBeeTransactionMatcher
        /// </summary>
        public async Task <CommandResult> SendTransaction(ZigBeeCommand command, IZigBeeTransactionMatcher responseMatcher)
        {
            _command         = command;
            _responseMatcher = responseMatcher;

            _timeout = DateTime.Now.AddMilliseconds(DEFAULT_TIMEOUT_MILLISECONDS);

            lock (_command)
            {
                _networkManager.AddCommandListener(this);

                int transactionId = _networkManager.SendCommand(command);

                if (command is ZclCommand cmd)
                {
                    cmd.TransactionId = (byte)transactionId;
                }
            }

            return(await Task.Run(() =>
            {
                while (true)
                {
                    if (DateTime.Now < _timeout)
                    {
                        if (_result != null)
                        {
                            return _result;
                        }
                    }
                    else
                    {
                        _logger.Debug("Transaction timeout: {Command}", _command);
                        lock (_command)
                        {
                            _networkManager.RemoveCommandListener(this);
                            return new CommandResult();
                        }
                    }
                }
            }));
        }
Пример #2
0
        /// <summary>
        /// Sends ZigBeeCommand command and uses the ZigBeeTransactionMatcher to match the response.
        /// The task will be timed out if there is no response.
        ///
        /// <param name="command">the ZigBeeCommand</param>
        /// <param name="responseMatcher">the ZigBeeTransactionMatcher</param>
        /// </summary>
        public async Task <CommandResult> SendTransaction(ZigBeeCommand command, IZigBeeTransactionMatcher responseMatcher)
        {
            CommandResult commandResult;

            lock (_objLock)
            {
                _command         = command;
                _responseMatcher = responseMatcher;
                _networkManager.AddCommandListener(this);

                int transactionId = _networkManager.SendCommand(command);

                if (command is ZclCommand cmd)
                {
                    cmd.TransactionId = (byte)transactionId;
                }
                //Without RunContinuationsAsynchronously, calling SetResult can block the calling thread, because the continuation is run synchronously
                //see https://stackoverflow.com/a/37492081
                _sendTransactionTask = new TaskCompletionSource <CommandResult>(TaskCreationOptions.RunContinuationsAsynchronously);
            }

            var t           = _sendTransactionTask.Task;
            var cancel      = new CancellationTokenSource();
            var timeoutTask = Task.Delay(Timeout, cancel.Token);

            if (t == await Task.WhenAny(t, timeoutTask).ConfigureAwait(false))
            {
                cancel.Cancel(); //Cancel the timeout task
                commandResult = t.Result;
            }
            else
            {
                /* Timeout */
                Log.Debug("Transaction timeout: {Command}", _command);
                commandResult = new CommandResult();
            }
            _networkManager.RemoveCommandListener(this);

            return(commandResult);
        }
Пример #3
0
 public async Task <CommandResult> SendTransaction(ZigBeeCommand command, IZigBeeTransactionMatcher responseMatcher)
 {
     return(await _network.SendTransaction(command, responseMatcher));
 }
Пример #4
0
 /// <summary>
 /// Sends <see cref="ZigBeeCommand"> command and uses the <see cref="ZigBeeTransactionMatcher"> to match the response.
 ///
 /// <param name="command">the <see cref="ZigBeeCommand"> to send</param>
 /// <param name="responseMatcher">the <see cref="ZigBeeTransactionMatcher"> used to match the response to the request</param>
 /// <returns>the <see cref="CommandResult"> future.</returns>
 /// </summary>
 public async Task <CommandResult> SendTransaction(ZigBeeCommand command, IZigBeeTransactionMatcher responseMatcher)
 {
     //command.DestinationAddress = GetEndpointAddress();
     return(await Node.SendTransaction(command, responseMatcher));
 }
Пример #5
0
        /// <summary>
        /// Sends ZigBeeCommand command and uses the ZigBeeTransactionMatcher to match the response.
        /// The task will be timed out if there is no response.
        ///
        /// <param name="command">the ZigBeeCommand</param>
        /// <param name="responseMatcher">the ZigBeeTransactionMatcher</param>
        /// </summary>
        public async Task <CommandResult> SendTransaction(ZigBeeCommand command, IZigBeeTransactionMatcher responseMatcher)
        {
            _command         = command;
            _responseMatcher = responseMatcher;
            _timeout         = DateTime.Now.AddMilliseconds(DEFAULT_TIMEOUT_MILLISECONDS);

            _networkManager.AddCommandListener(this);

            int transactionId = _networkManager.SendCommand(command);

            if (command is ZclCommand cmd)
            {
                cmd.TransactionId = (byte)transactionId;
            }

            _sendTransactionTask = new TaskCompletionSource <CommandResult>();
            var t           = _sendTransactionTask.Task;
            var timeoutTask = Task.Delay(DEFAULT_TIMEOUT_MILLISECONDS);
            var cancel      = new CancellationTokenSource();

            if (t == await Task.WhenAny(t, timeoutTask).ConfigureAwait(false))
            {
                cancel.Cancel(); //Cancel the timeout task
                _networkManager.RemoveCommandListener(this);
                return(t.Result);
            }
            else
            {
                /* Timeout */
                Log.Debug("Transaction timeout: {Command}", _command);

                _networkManager.RemoveCommandListener(this);

                return(new CommandResult());
            }

            /* !!! OLD CODE WITHOUT COMPLETION SOURCE - DO NOT DELET IT YET !!!
             *
             * return await Task.Run(() =>
             * {
             *  while (true)
             *  {
             *      if (DateTime.Now < _timeout)
             *      {
             *          if (_result != null)
             *          {
             *              return _result;
             *          }
             *      }
             *      else
             *      {
             *          Log.Debug("Transaction timeout: {Command}", _command);
             *          lock (_command)
             *          {
             *              _networkManager.RemoveCommandListener(this);
             *              return new CommandResult();
             *          }
             *      }
             *  }
             * });
             *
             */
        }