public async Task <MavParam> ReadParam(string name, int attemptCount, CancellationToken cancel) { var packet = new ParamRequestReadPacket { ComponenId = _config.ComponentId, SystemId = _config.SystemId, Payload = { TargetComponent = _config.TargetComponenId, TargetSystem = _config.TargetSystemId, ParamId = SetParamName(name), ParamIndex = -1, } }; byte currentAttempt = 0; MavParam result = null; while (currentAttempt < attemptCount) { ++currentAttempt; using (var timeoutCancel = new CancellationTokenSource(_config.ReadWriteTimeoutMs)) using (var linkedCancel = CancellationTokenSource.CreateLinkedTokenSource(cancel, timeoutCancel.Token)) { var eve = new AsyncAutoResetEvent(false); IDisposable subscribe = null; try { subscribe = OnParamUpdated.FirstAsync(_ => _.Name == name) .Subscribe(_ => { result = _; eve.Set(); }); await _connection.Send(packet, linkedCancel.Token).ConfigureAwait(false); await eve.WaitAsync(linkedCancel.Token); } catch (TaskCanceledException) { if (!timeoutCancel.IsCancellationRequested) { throw; } } finally { subscribe?.Dispose(); } return(result); } } if (result == null) { throw new TimeoutException(string.Format("Timeout to read param '{0}' with '{1}' attempts (timeout {1} times by {2:g} )", name, currentAttempt, TimeSpan.FromMilliseconds(_config.ReadWriteTimeoutMs))); } return(result); }
public async Task <MavParam> ReadParam(short index, int attemptCount, CancellationToken cancel) { _logger.Info($"Begin read param by index '{index}': BEGIN"); var packet = new ParamRequestReadPacket { ComponenId = _identity.ComponentId, SystemId = _identity.SystemId, Payload = { TargetComponent = _identity.TargetComponentId, TargetSystem = _identity.TargetSystemId, ParamId = SetParamName(string.Empty), ParamIndex = index, } }; byte currentAttempt = 0; MavParam result = null; while (currentAttempt < attemptCount) { ++currentAttempt; using (var timeoutCancel = new CancellationTokenSource(_config.ReadWriteTimeoutMs)) using (var linkedCancel = CancellationTokenSource.CreateLinkedTokenSource(cancel, timeoutCancel.Token)) { var eve = new AsyncAutoResetEvent(false); IDisposable subscribe = null; try { subscribe = OnParamUpdated.FirstAsync(_ => _.Index == index) .Subscribe(_ => { result = _; eve.Set(); }); await _connection.Send(packet, linkedCancel.Token).ConfigureAwait(false); await eve.WaitAsync(linkedCancel.Token); } catch (TaskCanceledException) { _logger.Warn($"Read param by index '{index}': TIMEOUT {currentAttempt} of {attemptCount}"); if (!timeoutCancel.IsCancellationRequested) { throw; } } finally { subscribe?.Dispose(); } return(result); } } if (result == null) { var ex = new TimeoutException(string.Format("Timeout to read param with index '{0}' with '{1}' attempts (timeout {1} times by {2:g} )", index, currentAttempt, TimeSpan.FromMilliseconds(_config.ReadWriteTimeoutMs))); _logger.Error(ex, $"Read param by index '{index}': {ex.Message}"); throw ex; } return(result); }