// ViewModel constructor public ViewModel() { TestProperty = "TEST"; IsInitializingWtm = true; ProfitTables = new ProfitTables { Tables = new ObservableCollection <ProfitTable>() }; ProfitTables.Tables.CollectionChanged += ProfitTables_CollectionChanged; HistoricalCharts = new ObservableCollection <HistoricalChart>(); // Read workers from file or create default Workers = Workers.ReadWorkers(false); if (Workers == null) { Workers = new Workers(true).Clone(); DefaultWorkers = true; } WorkersPropertyEventsAdd(); // Read Wtm settings from file or create default settings WtmSettings = WtmSettingsObject.ReadWtmSettings(false); if (WtmSettings == null) { WtmSettings = new WtmSettingsObject(); DefaultWtmSettings = true; } WhatToMine.RequestInterval = WtmSettings.WtmRequestInterval; WtmSettings.ServerSettingsAreUpdated = true; UpdateWtmHttpClient(); WtmSwitchTimeFromStored = WtmSettings.SwitchTimeFrom.Clone(); WtmSwitchTimeToStored = WtmSettings.SwitchTimeTo.Clone(); WtmHistoricalAveragePeriodStored = WtmSettings.HistoricalAveragePeriod; WtmHistoryTimeFromStored = WtmSettings.HistoryTimeFrom.Clone(); WtmHistoryTimeToStored = WtmSettings.HistoryTimeTo.Clone(); HookUpWmtSettingsPropertyChangeEvents(); SwitchTimeIsUpdated = true; HistoryTimeIsUpdated = true; History = new History(); ProfitTablesEnabled = true; Initialize = new RelayCommandLight(InitializeCommand); AddWorker = new RelayCommandLight(AddWorkerCommand); DeleteWorker = new RelayCommandLight(DeleteWorkerCommand); NewWorker = new RelayCommandLight(NewWorkerCommand); ExportWorkers = new RelayCommandLight(ExportWorkersCommand); ImportWorkers = new RelayCommandLight(ImportWorkersCommand); MultiplyHashrate = new RelayCommandLight(MultiplyHashrateCommand); MoveWorker = new RelayCommandLight(MoveWorkerCommand); CopyWorker = new RelayCommandLight(CopyWorkerCommand); MoveWorkerDown = new RelayCommandLight(MoveWorkerDownCommand); MoveWorkerUp = new RelayCommandLight(MoveWorkerUpCommand); AddCoinTable = new RelayCommandLight(AddCoinTableCommand); DeleteCoinTable = new RelayCommandLight(DeleteCoinTableCommand); MoveCoinTable = new RelayCommandLight(MoveCoinTableCommand); CopyCoinTable = new RelayCommandLight(CopyCoinTableCommand); AddCoin = new RelayCommandLight(AddCoinCommand); DeleteCoin = new RelayCommandLight(DeleteCoinCommand); Save = new RelayCommandLight(SaveCommand); Undo = new RelayCommandLight(UndoCommand); Redo = new RelayCommandLight(RedoCommand); CalculateProfit = new RelayCommandLight(CalculateProfitCommand, CalculateProfit_CanExecute); Export = new RelayCommandLight(ExportCommand, Export_CanExecute); SwitchManually = new RelayCommandLight(SwitchManuallyCommand, SwitchManually_CanExecute); ApplyAutoSwitch = new RelayCommandLight(ApplyAutoSwitchCommand); ApplyHistoryBackup = new RelayCommandLight(ApplyHistoryBackupCommand); EditKillList = new RelayCommandLight(EditKillListCommand); GenerateRandomPort = new RelayCommandLight(GenerateRandomPortCommand); ApplyServerSettings = new RelayCommandLight(ApplyServerSettingsCommand); TestConnection = new RelayCommandLight(TestConnectionCommand, TestConnection_CanExecute); LoadHistoricalCharts = new RelayCommandLight(LoadHistoricalChartsCommand, CalculateProfit_CanExecute); LineSeriesSelectAll = new RelayCommandLight(LineSeriesSelectAllCommand); LineSeriesSelectNone = new RelayCommandLight(LineSeriesSelectNoneCommand); ScanLan = new RelayCommandLight(ScanLanCommand); ScanLanStop = new RelayCommandLight(ScanLanStopCommand); ClearProfitTables = new RelayCommandLight(ClearProfitTablesCommand); MassUpdateApplication = new RelayCommandLight(MassUpdateApplicationCommand); MassUpdateWorkers = new RelayCommandLight(MassUpdateWorkersCommand); MassUpdateWtmSettings = new RelayCommandLight(MassUpdateWtmSettingsCommand); AddCoinsByAlgorithm = new RelayCommandLight(AddCoinsByAlgorithmCommand); UpdateCoins = new RelayCommandLight(UpdateCoinsCommand); AddComputers = new RelayCommandLight(AddComputersCommand); CancelWaiting = new RelayCommandLight(CancelWaitingCommand); EditPath = new RelayCommandLight(EditPathCommand); OpenInExplorer = new RelayCommandLight(OpenInExplorerCommand); SortBy = new RelayCommandLight(SortByCommand); WorkersExpandAll = new RelayCommandLight(WorkersExpandAllCommand); WorkersCollapseAll = new RelayCommandLight(WorkersCollapseAllCommand); WorkerSelectAll = new RelayCommandLight(WorkerSelectAllCommand); WorkerSelectNone = new RelayCommandLight(WorkerSelectNoneCommand); WorkerQueryAll = new RelayCommandLight(WorkerQueryAllCommand); WorkerQueryNone = new RelayCommandLight(WorkerQueryNoneCommand); About = new RelayCommandLight(AboutCommand); Exit = new RelayCommandLight(ExitCommand); Test = new RelayCommandLight(TestCommand); Instance = this; } // end ViewModel constructor
private async void StartCommand(object obj) { SwitchIsInProgress = true; ManualSwitchCancelSource = new CancellationTokenSource(); var token = ManualSwitchCancelSource.Token; var taskList = new List <Task>(); var jobCount = ProfitTables.Sum(x => x.Computers.Count); var failList = new List <ProfitTable>(); FlowDocument report = new FlowDocument(); int errorCount = 0; await Task.Run(() => { ReportTitle = $"Progress: 0 of {jobCount}."; int i = 1; foreach (var table in ProfitTables) { var currentCoinRow = table.ProfitList[0]; foreach (var pc in table.Computers) { pc.RestartStatus = pc.Restart ? Computer.OperationStatus.OperationInProgress : Computer.OperationStatus.Indeterminate; pc.SwitchStatus = pc.Switch ? Computer.OperationStatus.OperationInProgress : Computer.OperationStatus.Indeterminate; Func <Task> function = (async() => { var serverAddress = "net.tcp://" + pc.Name + ":" + NetHelper.Port + Constants.AccessPoint; var channel = Service.NewChannel(serverAddress, TimeSpan.FromSeconds(10)); try { try { if (pc.Switch) { bool switchResult = await channel.SetCurrentCoinAsync( currentCoinRow.Name, currentCoinRow.Symbol, currentCoinRow.Algorithm, currentCoinRow.Path, currentCoinRow.Arguments).WithCancellation(token); if (switchResult) { pc.SwitchStatus = Computer.OperationStatus.Success; } else { pc.SwitchStatus = Computer.OperationStatus.Failure; } } } catch (Exception ex) { errorCount++; pc.SwitchStatus = Computer.OperationStatus.Failure; Application.Current.Dispatcher.Invoke(() => { var p = new Paragraph(); p.Inlines.Add(new Run($"{table.Name}:").FontWeight(FontWeights.Bold).Color(Colors.Salmon)); p.Inlines.Add(new Run($"{pc.Name} Failed to switch to {currentCoinRow.NameAndSymbol}.\r\n")); p.Inlines.Add(new Run(ex.Message + "\r\n")); NewParagraph = p; }); if (pc.Restart) { pc.RestartStatus = Computer.OperationStatus.Failure; } else { pc.RestartStatus = Computer.OperationStatus.NotPossible; } return; } try { if (pc.Restart) { // Schedule delayed restart if pc is localhost if (string.Equals(pc.Name, Environment.MachineName, StringComparison.CurrentCultureIgnoreCase)) { RestartPending = true; pc.RestartStatus = Computer.OperationStatus.Pending; } else { bool restartResult = await channel.RestartComputerAsync(5).WithCancellation(token); if (restartResult) { pc.RestartStatus = Computer.OperationStatus.Success; } else { pc.RestartStatus = Computer.OperationStatus.Failure; } } } } catch (Exception ex) { errorCount++; pc.RestartStatus = Computer.OperationStatus.Failure; Application.Current.Dispatcher.Invoke(() => { var p = new Paragraph(); p.Inlines.Add(new Run($"{table.Name}:").FontWeight(FontWeights.Bold).Color(Colors.Salmon)); p.Inlines.Add(new Run($"{pc.Name} Failed to restart.\r\n")); p.Inlines.Add(new Run(ex.Message + "\r\n")); NewParagraph = p; }); } } finally { NetHelper.CloseChannel(channel); ReportTitle = $"Progress: {i} of {jobCount}."; i++; } }); // This line blocks UI upon DNS lookup of a non-existing or disconnected machine. // That is why the entire block is wrapped into Task.Run(). Task task = function(); taskList.Add(task); } } }); await Task.WhenAll(taskList); if (errorCount == 0) { ReportTitle = "Report:"; NewParagraph = new Paragraph(new Run("Operation has finished successfully.")); } else { ReportTitle = "Error report:"; } SwitchIsInProgress = false; SwitchIsFinished = true; }