public void Terminate(string commandName, TimeSpan?timeout = null) { CommandInvocation awaitedInvocation = null; lock (runningCommandsLock) { if (runningCommands.TryGetValue(commandName, out CommandInvocation invocation)) { if (!invocation.Terminable) { return; } awaitedInvocation = invocation; invocation.CancellationTokenSource?.Cancel(); } else { return; } } if (awaitedInvocation != null) { if (!awaitedInvocation.Task.Wait(timeout ?? TimeSpan.FromSeconds(30))) { throw new TimeoutException($"Cannot terminate command {awaitedInvocation.CommandName}"); } } }
private void NonNestedAction(Action action, CommandInvocation invocation) { AddCommandInvocation(invocation.Command, invocation); nestingLevel.Value += 1; commandHandler.OnCancellationTokenCreated(invocation.CancellationTokenSource.Token); try { action(); } catch (OperationCanceledException oce) { logger.Info($"Command '{invocation.Command.Name}' cancelled."); logger.Debug(oce.StackTrace); } catch (Exception ex) { logger.Error($"Command '{invocation.Command.Name}' threw exception:"); logger.Info(ex.ToString()); } finally { commandHandler.RemoveCommandInvocation(invocation); invocation.CancellationTokenSource.Dispose(); nestingLevel.Value -= 1; } }
private void AddCommandInvocation(CommandInvocation invocation) { lock (runningCommandsLock) { runningCommands.Add(invocation.Command.Name, invocation); } RunningCommandAdded?.Invoke(this, invocation); }
private bool AddCommandInvocation(Command command, CommandInvocation commandInvocation) { if (command.ExecutionMode == CommandExecutionMode.AlwaysParallel || nestingLevel.Value == 0) { commandHandler.AddCommandInvocation(commandInvocation); return(true); } return(false); }
private void NonNestedAction(Action action, string parameters, Command command, CancellationTokenSource cancellationTokenSource) { cancellationTokenSource = cancellationTokenSource ?? new CancellationTokenSource(); var commandInvocation = new CommandInvocation(command, parameters, command.ExecutionMode, nestingLevel.Value, cancellationTokenSource); var task = new Task(() => NonNestedAction(action, commandInvocation)); commandInvocation.Task = task; task.Start(); }
private void RemoveCommandInvocation(CommandInvocation invocation) { var removed = false; lock (runningCommandsLock) { if (runningCommands.ContainsKey(invocation.Command.Name)) { runningCommands.Remove(invocation.Command.Name); removed = true; } } if (removed) { RunningCommandRemoved?.Invoke(this, invocation); } }
private void NestedAction(Action action, Command command, string parameters, CancellationTokenSource cancellationTokenSource) { var invocation = new CommandInvocation(command, parameters, command.ExecutionMode, nestingLevel.Value, cancellationTokenSource); var commandAdded = AddCommandInvocation(command, invocation); if (command.Terminable) { if (cancellationTokenSource != null) { commandHandler.OnCancellationTokenCreated(cancellationTokenSource.Token); } } else { commandHandler.OnCancellationTokenCreated(CancellationToken.None); } nestingLevel.Value += 1; try { action(); } catch (OperationCanceledException) { logger.Info($"Command '{command.Name}' cancelled."); } finally { nestingLevel.Value -= 1; if (commandAdded) { commandHandler.RemoveCommandInvocation(invocation); } } }