using System; using System.Collections.ObjectModel; using System.Linq; using System.Threading; using sharpknife.Commands; using sharpknife.ViewModel; using System.Windows.Threading; using System.Collections.Generic; namespace sharpknife.Engines { public class CommandEngine : ViewModelBase, IDisposable { public enum StatusCode { Stopped, Running, Paused } public StatusCode Status { get; set; } private Thread thread; private static CommandEngine engine; public static CommandEngine GetEngine() { if (engine == null) engine = new CommandEngine(); return engine; } public ObservableCollection Commands { get; set; } private int waiting; public int Waiting { get { return waiting; } set { waiting = value; OnPropertyChanged("Waiting"); } } private CommandEngine() { Commands = new AsyncObservableCollection(); Commands.Clear(); Status = StatusCode.Stopped; } private void Engine() { Thread.Sleep(5000); while (Status == StatusCode.Running || Status == StatusCode.Paused) { if (Status == StatusCode.Running) { //var expiredCommands = (from c in Commands where c.Status == Command.StatusCode.Executing && c.TimedOut select c).ToList(); //foreach (Command command in expiredCommands) //{ // command.Expire(); //} var groups = new List(); try { groups = (from c in Commands where !(c.Status == Command.StatusCode.Executing || c.Status == Command.StatusCode.Paused) select c.Group).Distinct().ToList(); } catch (InvalidOperationException ex) { LogItem item = new LogItem(ex.Message); item.Save(); continue; } foreach (string _group in groups) { Command executingCommand = null; try { executingCommand = ( from c in Commands where (c.Status == Command.StatusCode.Executing || c.Status == Command.StatusCode.Paused) && c.Group == _group select c).FirstOrDefault(); } catch (InvalidOperationException ex) { LogItem item = new LogItem(ex.Message); item.Save(); continue; } if (executingCommand == null) { try { Command command = ( from c in Commands where (c.Status == Command.StatusCode.Waiting) && c.Group == _group && c.NextExecution <= DateTime.Now select c ).FirstOrDefault(); if (command != null) { //if (command.Status == Command.StatusCode.Waiting) { try { command.Status = Command.StatusCode.Executing; Thread thread = new Thread(new ThreadStart(() => { command.Execute(); })); thread.SetApartmentState(ApartmentState.STA); thread.Start(); } catch (Exception ex) { LogItem item = new LogItem(ex.ToString()); item.Save(); command.Status = Command.StatusCode.Failed; } } } } catch (InvalidOperationException ex) { LogItem item = new LogItem(ex.Message); item.Save(); continue; } } } } try { Waiting = (from c in Commands where c.Status == Command.StatusCode.Waiting select c).Count(); } catch (InvalidOperationException ex) { LogItem item = new LogItem(ex.Message); item.Save(); continue; } Thread.Sleep(1000); } } public void Start() { Status = StatusCode.Running; thread = new Thread(Engine); thread.SetApartmentState(ApartmentState.STA); thread.Start(); } public void Pause() { if (Status == StatusCode.Running) { Status = StatusCode.Paused; } } public void Resume() { if (Status == StatusCode.Paused) { Status = StatusCode.Running; } } public void Stop() { Status = StatusCode.Stopped; thread.Join(5000); thread.Abort(); } public void Dispose() { Stop(); } } }