public async Task <CycleProcessingContext> ProcessAsync(CycleProcessingContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (!context.IsValid()) { _logger.Warning($"{GetType().Name}: действие не будет выполнено, т.к. в обработке сеанса возникли ошибки"); return(context); } var needPumping = context.TryGetAutoPumpingRequestParams()?.IsAutoPumpingEnabled ?? false; _logger?.Trace($"{GetType().Name}: накачка манжеты..."); if (!needPumping) { _logger?.Trace($"{GetType().Name}: накачка манжеты не требуется"); context.AddOrUpdate(new PumpingResultContextParams(true)); return(context); } var isFree = await _mutex .WaitAsync(_blockWaitingTimeout) .ConfigureAwait(false); if (!isFree) { _logger?.Warning($"{GetType().Name}: предыдущий запрос еще выполняется. " + $"Новый запрос не будет выполнен, т.к. прошло больше {_blockWaitingTimeout.TotalMilliseconds} мс"); return(context); } var retryCounts = context.TryGetAutoPumpingRequestParams()?.PumpingNumberOfAttempts ?? 0; bool wasPumpingComleted; try { var timeoutPolicy = Policy .TimeoutAsync(_pumpingTimeout); var recilencePolicy = Policy .Handle <Exception>() .WaitAndRetryAsync( retryCounts, retryAttemp => TimeSpan.FromSeconds(_defaultRetryTimeout.TotalSeconds), (exception, timeSpan, localContext) => { _logger?.Trace($"{GetType().Name}: накачнка манжеты не выполена. Будет выполнена " + "повторная попытка."); }); var policyWrap = Policy.WrapAsync(recilencePolicy, timeoutPolicy); await policyWrap .ExecuteAsync(_monitorController.PumpCuffAsync) .ConfigureAwait(false); wasPumpingComleted = true; } catch (DeviceConnectionException e) { context.AddOrUpdate( new ExceptionCycleProcessingContextParams( new SessionProcessingException( SessionProcessingErrorCodes.MonitorConnectionError, e.Message, e))); wasPumpingComleted = false; } catch (TimeoutRejectedException e) { context.AddOrUpdate( new ExceptionCycleProcessingContextParams( new SessionProcessingException( SessionProcessingErrorCodes.PumpingTimeout, "Накачка манжеты прервана по таймауту", e))); wasPumpingComleted = false; } catch (DeviceProcessingException e) { context.AddOrUpdate( new ExceptionCycleProcessingContextParams( new SessionProcessingException( SessionProcessingErrorCodes.PumpingError, e.Message, e))); wasPumpingComleted = false; } catch (Exception e) { context.AddOrUpdate( new ExceptionCycleProcessingContextParams( new SessionProcessingException( SessionProcessingErrorCodes.PumpingError, e.Message, e))); wasPumpingComleted = false; } finally { _mutex.Release(); } context.AddOrUpdate(new PumpingResultContextParams(wasPumpingComleted)); return(context); }