protected async Task CommandAsync(Func <Task> command) { ThrowExceptionIfNotConnected(); Task tempTask = null; try { await CommandOrRequestPolicy.ExecuteAsync(async() => { tempTask = command.Invoke(); listOfCommandsOrRequestTasks.Add(tempTask); await tempTask; } , _ctKillCommandsRequested ); } finally { if (tempTask != null) { listOfCommandsOrRequestTasks.Remove(tempTask); } } }
private void ConfigureStateMachineAndTryBot() { _sm = new StateMachineNonBlockingProcessing <State, Trigger>(State.InitalNotConnected); _sm.Configure(State.InitalNotConnected) .Permit(Trigger.ConnectRequested, State.TryingToConnect); _sm.Configure(State.TryingToConnect) .OnEntry(() => { _sm.ProcessInsideAsync(async() => { try { _connectTask = DoConnectAsync(); await _connectTask; _sm.FireWithNoLock(Trigger.ConnectAttemptSucceeded); _connectDoneWait.Set(); } catch { _ctsConnectedFailed.Cancel(); _connectDoneWait.Set(); _sm.FireWithNoLock(Trigger.ConnectAttemptFailed); } }); Console.WriteLine($"Entered State {nameof(State.TryingToConnect)}"); } ) .Permit(Trigger.ConnectAttemptSucceeded, State.Connected) .Permit(Trigger.ConnectAttemptFailed, State.TryingToReconnect); _sm.Configure(State.TryingToReconnect) .OnEntry(() => { _sm.ProcessInsideAsync(async() => { try { _connectDoneWait.Reset(); _reconnectDoneWait.Reset(); await ReconnectPolicy.ExecuteAsync(async() => await DoReconnectAsync()); _sm.FireWithNoLock(Trigger.ConnectAttemptSucceeded); _connectDoneWait.Set(); _reconnectDoneWait.Set(); } catch (Exception ex) { //** FatalW } }); Console.WriteLine($"Entered State {nameof(State.TryingToReconnect)}"); }) .Permit(Trigger.ConnectAttemptSucceeded, State.Connected) .Permit(Trigger.CloseRequested, State.Closing); _sm.Configure(State.Connected) .Permit(Trigger.ErrorOccurred, State.ErrorEncounteredRetrying) .Permit(Trigger.CloseRequested, State.Closing); _sm.Configure(State.ErrorEncounteredRetrying) .Ignore(Trigger.ErrorOccurred) .Permit(Trigger.CloseRequested, State.Closing) .Permit(Trigger.ErrorWasRecoveredFrom, State.Connected) .Permit(Trigger.ErrorWasUnrecoverable, State.TryingToReconnect); _sm.Configure(State.Closing) .OnEntry(() => { DoCloseAsync(); _sm.FireWithNoLock(Trigger.CloseCompleted); _closeDoneWait.Set(); }) .Permit(Trigger.CloseCompleted, State.Closed); ReconnectPolicy = new BotPolicy(policy => policy.Configure(config => config .Retry(retryConfig => retryConfig .WhenExceptionOccurs(exception => exception is DeviceConnectionException) .RetryIndefinitely()) )); const int retryLimit = 5; CommandOrRequestPolicy = new BotPolicy(policy => policy.Configure(config => config .Retry(retryConfig => retryConfig .WhenExceptionOccurs(exception => exception is DeviceConnectionException) .WithMaxAttemptCount(retryLimit) .OnRetry((ex, context) => { //_ctKillCommandsRequested.ThrowIfCancellationRequested(); _sm.FireWithNoLock(Trigger.ErrorOccurred); }) .OnRetrySucceeded((context) => { _sm.FireIfPermittedNoLock(Trigger.ErrorWasRecoveredFrom); }) ) .Fallback(fallbackConfig => fallbackConfig .WhenExceptionOccurs((exception) => exception is Trybot.Retry.Exceptions.MaxRetryAttemptsReachedException) .OnFallback((exception, executionContext) => { CancelAllCommandsAndWait().Wait(); _sm.FireWithNoLock(Trigger.ErrorWasUnrecoverable); void ThrowException() { throw new DeviceConnectionException($"Retry Count of {retryLimit} Exceeded", exception); } ThrowException(); })) )); }
/// <summary> /// Executes an action asynchronously within the bot policy and returns with its result. /// </summary> /// <param name="policy">The policy.</param> /// <param name="operation">The asynchronous operation to execute.</param> /// <param name="token">Tha cancellation token.</param> /// <returns>The task to await.</returns> public static Task <TResult> ExecuteAsync <TResult>(this IBotPolicy <TResult> policy, Func <ExecutionContext, CancellationToken, Task <TResult> > operation, CancellationToken token = default) => policy.ExecuteAsync(new AsyncBotOperation <TResult>(operation), Guid.NewGuid(), token);
/// <summary> /// Executes an action asynchronously within the bot policy. /// </summary> /// <param name="policy">The policy.</param> /// <param name="operation">The asynchronous operation to execute.</param> /// <param name="token">Tha cancellation token.</param> /// <returns>The task to await.</returns> public static Task ExecuteAsync(this IBotPolicy policy, Func <Task> operation, CancellationToken token = default) => policy.ExecuteAsync(new AsyncParameterlessBotOperation(operation), Guid.NewGuid(), token);
/// <summary> /// Executes an action asynchronously within the bot policy. /// </summary> /// <param name="policy">The policy.</param> /// <param name="action">The action to execute.</param> /// <param name="token">Tha cancellation token.</param> /// <returns>The task to await.</returns> public static Task ExecuteAsync(this IBotPolicy policy, Action <ExecutionContext, CancellationToken> action, CancellationToken token = default) => policy.ExecuteAsync(new AsyncBotOperation(action), Guid.NewGuid(), token);
/// <summary> /// Executes an action asynchronously within the bot policy and returns with its result. /// </summary> /// <param name="policy">The policy.</param> /// <param name="operation">The asynchronous operation to execute.</param> /// <param name="correlationId">The correlation id.</param> /// <param name="token">Tha cancellation token.</param> /// <returns>The task to await.</returns> public static Task <TResult> ExecuteAsync <TResult>(this IBotPolicy <TResult> policy, Func <ExecutionContext, CancellationToken, Task <TResult> > operation, object correlationId, CancellationToken token = default) => policy.ExecuteAsync(new AsyncBotOperation <TResult>(operation), correlationId, token);
/// <summary> /// Executes an action asynchronously within the bot policy. /// </summary> /// <param name="policy">The policy.</param> /// <param name="action">The action to execute.</param> /// <param name="correlationId">The correlation id.</param> /// <param name="token">Tha cancellation token.</param> /// <returns>The task to await.</returns> public static Task ExecuteAsync(this IBotPolicy policy, Action <ExecutionContext, CancellationToken> action, object correlationId, CancellationToken token = default) => policy.ExecuteAsync(new AsyncBotOperation(action), correlationId, token);
/// <summary> /// Executes an action asynchronously within the bot policy and returns with its result. /// </summary> /// <param name="policy">The policy.</param> /// <param name="operation">The asynchronous operation to execute.</param> /// <param name="correlationId">The correlation id.</param> /// <param name="token">Tha cancellation token.</param> /// <returns>The task to await.</returns> public static Task <TResult> ExecuteAsync <TResult>(this IBotPolicy <TResult> policy, Func <TResult> operation, object correlationId, CancellationToken token = default) => policy.ExecuteAsync(new AsyncParameterlessBotOperation <TResult>(operation), correlationId, token);
/// <summary> /// Executes an action asynchronously within the bot policy. /// </summary> /// <param name="policy">The policy.</param> /// <param name="action">The action to execute.</param> /// <param name="correlationId">The correlation id.</param> /// <param name="token">Tha cancellation token.</param> /// <returns>The task to await.</returns> public static Task ExecuteAsync(this IBotPolicy policy, Action action, object correlationId, CancellationToken token = default) => policy.ExecuteAsync(new AsyncParameterlessBotOperation(action), correlationId, token);