public void HandleCommand(string cmd, string method, string argString) { if (string.IsNullOrEmpty(method) || method == "ToString") { OutWriter.WriteLine(ToString()); return; } if (method == "Cancel") { if (TokenSource == null) { throw new CommandException("No task to cancel."); } else if (Task?.IsCompleted == true) { throw new CommandException("Task has already completed."); } else if (TokenSource.IsCancellationRequested) { throw new CommandException("Task has already had cancellation requested."); } else { TokenSource.Cancel(); } return; } if (Task?.IsCompleted == false) { throw new CommandException($"Programmer is busy. Current task: {LastCommand}"); } var args = argString.Split(' ', StringSplitOptions.RemoveEmptyEntries); Task t = null; TokenSource = new CancellationTokenSource(); byte?stationID = args.Length >= 1 ? ParseStationID(args[0]) : null; bool demandRelay = args.Length >= 2 && bool.TryParse(args[1], out var tmpDemandRelay) && tmpDemandRelay; switch (method) { case "BulkUpload": case "Bulk": case "B": case nameof(RemoteProgrammer.BulkUploadToStation): if (stationID == null) { throw new CommandException($"BulkUpload requires station ID as first parameter (can be zero)."); } t = Programmer.BulkUploadToStation(stationID.Value, demandRelay, TokenSource.Token); break; case "Complete": case "CompleteUpload": case "CU": case nameof(RemoteProgrammer.CompleteUploadToStationAsync): if (stationID == null) { throw new CommandException("CompleteUpload requires station ID as first parameter (cannot be zero)."); } t = Programmer.CompleteUploadToStationAsync(stationID.Value, TokenSource.Token); break; case "Confirm": case "CP": case nameof(RemoteProgrammer.ConfirmProgramming): if (stationID == null) { throw new CommandException("ConfirmProgramming requires stationID as first parameter (cannot be zero)."); } Programmer.ConfirmProgramming(stationID.Value); break; case "Go": case nameof(RemoteProgrammer.GoAsync): if (args.Length < 1) { throw new CommandException("Go requires stationID list as first parameter (cannot contain zero)."); } var stationIDs = args[0].Split(',').Select(str => byte.Parse(str)); TimeSpan timeout = TimeSpan.FromMinutes(5); if (args.Length >= 2) { timeout = TimeSpan.FromSeconds(double.Parse(args[1])); } bool confirm = false; if (args.Length >= 3) { confirm = bool.Parse(args[2]); } t = Programmer.GoAsync(stationIDs, demandRelay, timeout, confirm); break; case "Init": case "I": case nameof(RemoteProgrammer.InitUploadToStation): if (stationID == null) { throw new CommandException("InitUpload requires stationID as first parameter (can be zero)."); } Programmer.InitUploadToStation(stationID.Value, demandRelay); break; case "Query": case "Q": case nameof(RemoteProgrammer.QueryStationProgramming): Programmer.QueryStationProgramming(stationID ?? 0); break; case "Timeout": case nameof(RemoteProgrammer.ResponseTimeout): if (args.Length < 1 || !double.TryParse(args[0], out var timeoutSeconds)) { throw new CommandException("Cannot parse timeout seconds."); } Programmer.ResponseTimeout = TimeSpan.FromSeconds(timeoutSeconds); break; case "Interval": case nameof(RemoteProgrammer.PacketInterval): if (args.Length < 1 || !double.TryParse(args[0], out var intervalSeconds)) { throw new CommandException("Cannot parse interval seconds."); } Programmer.PacketInterval = TimeSpan.FromSeconds(intervalSeconds); break; case "ReadRemote": case nameof(RemoteProgrammer.ReadRemoteImageAsync): if (stationID == null) { throw new CommandException("ReadRemote requires stationID as first parameter"); } t = Programmer.ReadRemoteImageAsync(stationID.Value, TokenSource.Token) .ContinueWith(task => File.WriteAllText(Path.ChangeExtension(Programmer.Fn, ".remote"), task.Result.ToCsv(b => b.ToString("X2"), Environment.NewLine))); break; default: throw new CommandException($"Command {cmd} not recognised."); } if (t == null) { TokenSource = null; } Task = t; t?.ContinueWith(T => { if (T.IsFaulted) { OutWriter.WriteLine($"{ID}: Exception performing: {LastCommand}"); OutWriter.WriteLine(T.Exception); } else if (T.IsCanceled) { OutWriter.WriteLine($"{ID}: Task canceled: {LastCommand}"); } else { OutWriter.WriteLine($"{ID}: Task completed: {LastCommand}"); } }); LastCommand = cmd; }