private Action mapAction(MainForm formHandle, Actionable action, Dictionary<string, int> serverMap, CancellationToken token) { return new Action(() => { var gridTasks = new List<Task>(); foreach (string serverName in serverMap.Keys) { int x = serverMap[serverName]; gridTasks.Add(Task.Factory.StartNew(() => formHandle.setServerData(x, action.Name, "\u231B", getColorForActionStatus(ActionStatus.Queued)))); } Task.WaitAll(gridTasks.ToArray()); try { int atOnce; if (action.MaxRunning == -1) atOnce = serverMap.Keys.Count; else atOnce = action.MaxRunning; int segments = serverMap.Keys.Count / atOnce; if (segments * atOnce < serverMap.Keys.Count) segments++; var keys = serverMap.Keys.ToArray(); for (int i = 0; i < segments; i++) { var tasks = new List<Task>(); for (int j = i * atOnce; j < (i * atOnce) + atOnce; j++) { if (j < serverMap.Keys.Count) { string serverName = keys[j]; int x = serverMap[serverName]; string name = serverName; tasks.Add(Task.Factory.StartNew(() => { try { formHandle.setServerData(x, action.Name, "In progress...", getColorForActionStatus(ActionStatus.Pending)); Task<ActionResult> t = Task.Factory.StartNew<ActionResult>(wrapFunc(action.WorkFunc, name), token); t.Wait(token); string result; if (action.Post != null) { result = action.Post.Invoke(t.Result.Message); } else { result = t.Result.Message; } formHandle.setServerData(x, action.Name, result, getColorForActionStatus(t.Result.Status)); } catch (Exception e) { formHandle.setServerData(x, action.Name, "Operation cancelled.", getColorForActionStatus(ActionStatus.Unknown)); } }, token)); } } try { Task.WaitAll(tasks.ToArray(), token); } catch (OperationCanceledException opex) { throw opex; } } formHandle.addToActionLog("Completed: " + action.Name); action.Running = false; formHandle.refreshActionListControls(); if (action.Repeat) this.Run(action.Name, formHandle.getEnabledServers()); } catch (OperationCanceledException opex) { var indices = serverMap.Values.ToList(); var stillPending = formHandle.getPendingIndices(indices, action.Name); foreach (int i in stillPending) { formHandle.setServerData(i, action.Name, "Operation cancelled.", getColorForActionStatus(ActionStatus.Unknown)); } formHandle.addToActionLog("Cancelled: " + action.Name); action.Running = false; formHandle.refreshActionListControls(); } lock (action.runLock) { action.Running = false; } }); }
public ActionRunner(MainForm form) { actions = new Dictionary<string, Actionable>(); _form = form; }