Loading Samples/DeviceLab/CommandSequence.cs +87 −11 Original line number Diff line number Diff line Loading @@ -7,21 +7,73 @@ using System.Windows.Input; namespace DeviceLab { public class ObservableCommandQueue { private Queue<ICommand> commands; public ObservableCommandQueue() { this.commands = new Queue<ICommand>(); } public event EventHandler QueueChanged; public int Count { get { return this.commands.Count; } } public void Clear() { this.commands.Clear(); OnQueueChanged(); } public ICommand Peek() { return this.commands.Peek(); } public void Enqueue(ICommand cmd) { this.commands.Enqueue(cmd); OnQueueChanged(); } public ICommand Dequeue() { ICommand cmd = this.commands.Dequeue(); OnQueueChanged(); return cmd; } private void OnQueueChanged() { this.QueueChanged?.Invoke(this, new EventArgs()); } } public class CommandSequence : ICommand { private List<ICommand> registeredCommands; private Queue<ICommand> commandQueue; private ObservableCommandQueue commandQueue; private object sharedParameter; //------------------------------------------------------------------- // Constructor //------------------------------------------------------------------- #region Constructor public CommandSequence(Queue<ICommand> commandQueue = null) public CommandSequence(ObservableCommandQueue commandQueue = null) { this.registeredCommands = new List<ICommand>(); this.commandQueue = commandQueue == null ? new Queue<ICommand>() : commandQueue; this.commandQueue = commandQueue == null ? new ObservableCommandQueue() : commandQueue; this.commandQueue.QueueChanged += CommandQueue_QueueChanged; } #endregion // Constructor //------------------------------------------------------------------- Loading @@ -44,28 +96,48 @@ namespace DeviceLab CommandSequence seq = cmd as CommandSequence; if (seq == null) { this.registeredCommands.Add(cmd); AddCommand(cmd); } else { foreach (ICommand subcmd in seq.registeredCommands) { this.registeredCommands.Add(subcmd); AddCommand(subcmd); } } } OnCanExecuteChanged(); } private void AddCommand(ICommand cmd) { if(this.registeredCommands.Count == 0) { cmd.CanExecuteChanged += Forward_CanExecuteChanged; } this.registeredCommands.Add(cmd); } //------------------------------------------------------------------- // ICommand Implementation //------------------------------------------------------------------- public event EventHandler CanExecuteChanged; private void OnCanExecuteChanged() { this.CanExecuteChanged?.Invoke(this, new EventArgs()); } /// <summary> /// Forward on the CanExecuteChanged event from the first command in the list /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Forward_CanExecuteChanged(object sender, EventArgs e) { this.CanExecuteChanged?.Invoke(sender, e); } public bool CanExecute(object parameter) { if (this.registeredCommands.Count == 0) Loading Loading @@ -106,9 +178,12 @@ namespace DeviceLab private void CurrentCommand_CanExecuteChanged(object sender, EventArgs e) { ICommand cmd = sender as ICommand; if (cmd.CanExecute(this.sharedParameter)) { cmd.CanExecuteChanged -= CurrentCommand_CanExecuteChanged; ExecuteNext(); } } private void ExecuteNext() { Loading @@ -124,11 +199,12 @@ namespace DeviceLab { this.commandQueue.Peek().CanExecuteChanged += CurrentCommand_CanExecuteChanged; } else { OnCanExecuteChanged(); } } private void CommandQueue_QueueChanged(object sender, EventArgs e) { OnCanExecuteChanged(); } } } Samples/DeviceLab/DeviceLab.csproj +1 −0 Original line number Diff line number Diff line Loading @@ -64,6 +64,7 @@ <Compile Include="DeviceCollectionView.xaml.cs"> <DependentUpon>DeviceCollectionView.xaml</DependentUpon> </Compile> <Compile Include="DevicePortalCommandModel.cs" /> <Compile Include="DevicePortalViewModel.cs" /> <Compile Include="DeviceSignInView.xaml.cs"> <DependentUpon>DeviceSignInView.xaml</DependentUpon> Loading Samples/DeviceLab/DevicePortalCommandModel.cs 0 → 100644 +81 −0 Original line number Diff line number Diff line using Microsoft.Tools.WindowsDevicePortal; using Prism.Commands; using Prism.Mvvm; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Input; namespace DeviceLab { public class DevicePortalCommandModel : BindableBase { //------------------------------------------------------------------- // Protected Members //------------------------------------------------------------------- #region Protected Members protected IDiagnosticSink diagnostics; protected DevicePortal portal; #endregion // Protected Members //------------------------------------------------------------------- // Constructors //------------------------------------------------------------------- #region Constructors public DevicePortalCommandModel(DevicePortal portal, IDiagnosticSink diags) { this.portal = portal; this.diagnostics = diags; this.commandQueue = new ObservableCommandQueue(); this.Ready = true; } #endregion // Constructors //------------------------------------------------------------------- // Properties //------------------------------------------------------------------- #region Properties /// <summary> /// The Ready property indicates that there are no REST calls in flight via /// the underlying DevicePortal object /// </summary> #region Ready private bool ready; public bool Ready { get { return this.ready; } protected set { SetProperty(ref this.ready, value); } } #endregion // Ready #endregion // Properties //------------------------------------------------------------------- // Command Sequences //------------------------------------------------------------------- #region Command Sequences private ObservableCommandQueue commandQueue; protected void ClearCommandQueue() { this.commandQueue.Clear(); } public CommandSequence CreateCommandSequence() { return new CommandSequence(this.commandQueue); } #endregion // Command Sequences } } Samples/DeviceLab/DevicePortalViewModel.cs +80 −95 Original line number Diff line number Diff line Loading @@ -12,35 +12,16 @@ using static Microsoft.Tools.WindowsDevicePortal.DevicePortal; namespace DeviceLab { public class DevicePortalViewModel : BindableBase { //------------------------------------------------------------------- // Private Members //------------------------------------------------------------------- #region Private Members private IDiagnosticSink diagnostics; private string diagnosticMoniker public class DevicePortalViewModel : DevicePortalCommandModel { get { return !string.IsNullOrWhiteSpace(this.deviceName) ? this.deviceName : this.Address; } } #endregion // Private Members //------------------------------------------------------------------- // Constructors //------------------------------------------------------------------- #region Constructors public DevicePortalViewModel(DevicePortal portal, IDiagnosticSink diags) : base(portal, diags) { this.ConnectionRetryAttempts = 5; this.diagnostics = diags; this.portal = portal; this.Ready = true; } #endregion // Cosntructors Loading @@ -48,38 +29,15 @@ namespace DeviceLab // Properties //------------------------------------------------------------------- #region Properties #region Portal private DevicePortal portal; private DevicePortal Portal { get { return this.portal; } set { SetProperty(ref this.portal, value); OnPropertyChanged("Address"); OnPropertyChanged("DeviceFamily"); OnPropertyChanged("OperatingSystemVersion"); OnPropertyChanged("Platform"); OnPropertyChanged("PlatformName"); } } #endregion // Portal #region Ready private bool ready; public bool Ready #region Diagnostic Moniker private string diagnosticMoniker { get { return this.ready; } private set { SetProperty(ref this.ready, value); return !string.IsNullOrWhiteSpace(this.deviceName) ? this.deviceName : this.Address; } } #endregion // Ready #endregion // Diagnostic Moniker #region DeviceName private string deviceName; Loading Loading @@ -197,16 +155,20 @@ namespace DeviceLab #region Commands #region RenameCommand private DelegateCommand renameCommand; private CommandSequence renameCommand; public ICommand RenameCommand { get { if(this.renameCommand == null) { this.renameCommand = DelegateCommand.FromAsyncHandler(ExecuteRenameAsync, CanExecuteRename); this.renameCommand.ObservesProperty(() => this.Ready); this.renameCommand.ObservesProperty(() => this.DeviceNameEntry); this.renameCommand = CreateCommandSequence(); DelegateCommand renameDC = DelegateCommand.FromAsyncHandler(ExecuteRenameAsync, CanExecuteRename); renameDC.ObservesProperty(() => this.Ready); renameDC.ObservesProperty(() => this.DeviceNameEntry); this.renameCommand.RegisterCommand(renameDC); this.renameCommand.RegisterCommand(this.RebootCommand); this.renameCommand.RegisterCommand(this.RefreshDeviceNameCommand); } return this.renameCommand; } Loading @@ -214,6 +176,8 @@ namespace DeviceLab private bool CanExecuteRename() { //return // this.Ready; return this.Ready && !string.IsNullOrWhiteSpace(this.deviceNameEntry); Loading @@ -221,42 +185,35 @@ namespace DeviceLab private async Task ExecuteRenameAsync() { this.diagnostics.OutputDiagnosticString("[{0}] ExecuteRenameAsync\n", this.diagnosticMoniker); this.Ready = false; try { string newName = this.deviceNameEntry; this.DeviceNameEntry = ""; this.diagnostics.OutputDiagnosticString("[{0}] Attempting to rename device to {1}\n", this.diagnosticMoniker, newName); await this.Portal.SetDeviceName(newName); await this.portal.SetDeviceName(newName); } catch (Exception exn) { ReportException("Rename", exn); } await ExecuteRebootAsync(); if (this.Ready) { await RefreshDeviceNameAsync(); } else { // TODO: Need to decide what to do if this.Ready == false; // ALTERNATIVLEY: Need to decide how to recover after an error } this.Ready = true; } #endregion // RenameCommand #region RefreshDeviceName private DelegateCommand refreshDeviceNameCommand; private CommandSequence refreshDeviceNameCommand; public ICommand RefreshDeviceNameCommand { get { if(this.refreshDeviceNameCommand == null) { this.refreshDeviceNameCommand = DelegateCommand.FromAsyncHandler(RefreshDeviceNameAsync, CanExecuteRefreshDeviceName); this.refreshDeviceNameCommand.ObservesProperty(() => this.Ready); DelegateCommand refreshDeviceNameDC = DelegateCommand.FromAsyncHandler(RefreshDeviceNameAsync, CanExecuteRefreshDeviceName); refreshDeviceNameDC.ObservesProperty(() => this.Ready); this.refreshDeviceNameCommand = CreateCommandSequence(); this.refreshDeviceNameCommand.RegisterCommand(refreshDeviceNameDC); } return this.refreshDeviceNameCommand; } Loading @@ -269,30 +226,36 @@ namespace DeviceLab private async Task RefreshDeviceNameAsync() { this.diagnostics.OutputDiagnosticString("[{0}] RefreshDeviceNameAsync\n", this.diagnosticMoniker); this.Ready = false; try { this.DeviceName = await this.Portal.GetDeviceName(); this.DeviceName = await this.portal.GetDeviceName(); } catch (Exception exn) { ReportException("RefreshDeviceName", exn); } this.diagnostics.OutputDiagnosticString("[{0}] Retrieved device name.\n", this.diagnosticMoniker); this.Ready = true; } #endregion // RefreshDeviceName #region Reboot Command private DelegateCommand rebootCommand; private CommandSequence rebootCommand; public ICommand RebootCommand { get { if(this.rebootCommand == null) { this.rebootCommand = DelegateCommand.FromAsyncHandler(ExecuteRebootAsync, CanExecuteReboot); this.rebootCommand.ObservesProperty(() => this.Ready); this.rebootCommand = CreateCommandSequence(); DelegateCommand rebootDC = DelegateCommand.FromAsyncHandler(ExecuteRebootAsync, CanExecuteReboot); rebootDC.ObservesProperty(() => this.Ready); this.rebootCommand.RegisterCommand(StopListeningForSystemPerfCommand); this.rebootCommand.RegisterCommand(rebootDC); this.rebootCommand.RegisterCommand(this.ReestablishConnectionCommand); this.rebootCommand.RegisterCommand(this.refreshDeviceNameCommand); this.rebootCommand.RegisterCommand(this.StartListeningForSystemPerfCommand); } return this.rebootCommand; } Loading @@ -305,12 +268,12 @@ namespace DeviceLab private async Task ExecuteRebootAsync() { await ExecuteStopListeningForSystemPerfAsync(); this.diagnostics.OutputDiagnosticString("[{0}] ExecuteRebootAsync\n", this.diagnosticMoniker); this.Ready = false; try { this.diagnostics.OutputDiagnosticString("[{0}] Attempting to reboot device.\n", this.diagnosticMoniker); await this.Portal.Reboot(); await this.portal.Reboot(); // Sometimes able to reestablish the connection prematurely before the console has a chance to shut down // So adding a delay here before trying to reestablish the connection. Loading @@ -320,21 +283,22 @@ namespace DeviceLab { ReportException("Reboot", exn); } await ExecuteReestablishConnectionAsync(); await ExecuteStartListeningForSystemPerfAsync(); this.Ready = true; } #endregion // Reboot Command #region ReestablishConnectionCommand private DelegateCommand reestablishConnectionCommand; private CommandSequence reestablishConnectionCommand; public ICommand ReestablishConnectionCommand { get { if(this.reestablishConnectionCommand == null) { this.reestablishConnectionCommand = DelegateCommand.FromAsyncHandler(ExecuteReestablishConnectionAsync, CanExecuteReestablishConnection); this.reestablishConnectionCommand.ObservesProperty(() => this.Ready); this.reestablishConnectionCommand = CreateCommandSequence(); DelegateCommand reestablishConnectionDC = DelegateCommand.FromAsyncHandler(ExecuteReestablishConnectionAsync, CanExecuteReestablishConnection); reestablishConnectionDC.ObservesProperty(() => this.Ready); this.reestablishConnectionCommand.RegisterCommand(reestablishConnectionDC); } return this.reestablishConnectionCommand; } Loading @@ -347,6 +311,7 @@ namespace DeviceLab private async Task ExecuteReestablishConnectionAsync() { this.diagnostics.OutputDiagnosticString("[{0}] ExecuteReestablishConnectionAsync\n", this.diagnosticMoniker); int numTries = 1; DeviceConnectionStatusEventHandler handler = (DevicePortal sender, DeviceConnectionStatusEventArgs args) => Loading @@ -371,26 +336,28 @@ namespace DeviceLab await this.portal.Connect(); ++numTries; } while (this.portal.ConnectionHttpStatusCode != HttpStatusCode.OK && numTries < this.ConnectionRetryAttempts); this.Ready = true; } catch (Exception exn) { ReportException("ReestablishConnection", exn); } this.portal.ConnectionStatus -= handler; this.Ready = true; } #endregion // ReestablishConnectionCommand #region StartListeningForSystemPerfCommand private DelegateCommand startListeningForSystemPerfCommand; private CommandSequence startListeningForSystemPerfCommand; public ICommand StartListeningForSystemPerfCommand { get { if(this.startListeningForSystemPerfCommand == null) { this.startListeningForSystemPerfCommand = DelegateCommand.FromAsyncHandler(ExecuteStartListeningForSystemPerfAsync, CanStartListeningForSystemPerf); this.startListeningForSystemPerfCommand.ObservesProperty(() => this.Ready); this.startListeningForSystemPerfCommand = CreateCommandSequence(); DelegateCommand startListeningForSystemPerfDC = DelegateCommand.FromAsyncHandler(ExecuteStartListeningForSystemPerfAsync, CanStartListeningForSystemPerf); startListeningForSystemPerfDC.ObservesProperty(() => this.Ready); this.startListeningForSystemPerfCommand.RegisterCommand(startListeningForSystemPerfDC); } return startListeningForSystemPerfCommand; } Loading @@ -403,9 +370,17 @@ namespace DeviceLab private async Task ExecuteStartListeningForSystemPerfAsync() { this.diagnostics.OutputDiagnosticString("[{0}] ExecuteStartListeningForSystemPerfAsync\n", this.diagnosticMoniker); this.Ready = false; try { this.portal.SystemPerfMessageReceived += OnSystemPerfReceived; await Task.Run(StartListeningHelper); } catch(Exception exn) { ReportException("StartListeningForSystemPerf", exn); } this.Ready = true; } Loading @@ -413,19 +388,20 @@ namespace DeviceLab { await this.portal.StartListeningForSystemPerf().ConfigureAwait(false); } #endregion // StartListeningForSystemPerfCommand #region StopListeningForSystemPerfCommand private DelegateCommand stopListeningForSystemPerfCommand; private CommandSequence stopListeningForSystemPerfCommand; public ICommand StopListeningForSystemPerfCommand { get { if(this.stopListeningForSystemPerfCommand == null) { this.stopListeningForSystemPerfCommand = DelegateCommand.FromAsyncHandler(ExecuteStopListeningForSystemPerfAsync, CanStopListeningForSystemPerf); this.stopListeningForSystemPerfCommand.ObservesProperty(() => this.Ready); this.stopListeningForSystemPerfCommand = CreateCommandSequence(); DelegateCommand stopListeningForSystemPerfDC = DelegateCommand.FromAsyncHandler(ExecuteStopListeningForSystemPerfAsync, CanStopListeningForSystemPerf); stopListeningForSystemPerfDC.ObservesProperty(() => this.Ready); this.stopListeningForSystemPerfCommand.RegisterCommand(stopListeningForSystemPerfDC); } return stopListeningForSystemPerfCommand; } Loading @@ -438,11 +414,18 @@ namespace DeviceLab private async Task ExecuteStopListeningForSystemPerfAsync() { this.diagnostics.OutputDiagnosticString("[{0}] ExecuteStopListeningForSystemPerfAsync\n", this.diagnosticMoniker); this.Ready = false; try { this.portal.SystemPerfMessageReceived -= OnSystemPerfReceived; await StopListeningHelper(); //await Task.Run(StopListeningHelper); await StopListeningHelper(); } catch(Exception exn) { ReportException("StopListeningForSystemPerf", exn); } this.Ready = true; } Loading @@ -453,8 +436,6 @@ namespace DeviceLab #endregion // StopListeningForSystemPerfCommand #endregion // Commands private void OnSystemPerfReceived(DevicePortal sender, WebSocketMessageReceivedEventArgs<DevicePortal.SystemPerformanceInformation> args) { this.cpuLoad = args.Message.CpuLoad; Loading @@ -466,6 +447,10 @@ namespace DeviceLab this.diagnostics.OutputDiagnosticString( "[{0}] Exception during {1} command:\n[{0}] {2}\nStackTrace: \n[{0}] {3}\n", this.diagnosticMoniker, commandName, exn.Message, exn.StackTrace); // Clear the command queue to prevent executing any more commands this.diagnostics.OutputDiagnosticString("[{0}] Clearing any queued commands\n", this.diagnosticMoniker); ClearCommandQueue(); } } } Samples/DeviceLab/MainViewModel.cs +3 −4 Original line number Diff line number Diff line Loading @@ -34,7 +34,6 @@ namespace DeviceLab } #endregion // Constructors private void OnSignInAttemptCompleted(DeviceSignInViewModel sender, DeviceSignInEventArgs args) { DevicePortal portal = args.Portal; Loading Loading @@ -310,7 +309,7 @@ namespace DeviceLab { dpvm.PropertyChanged += DevicePropertyChanged; CommandSequence cmdSeq = new CommandSequence(); CommandSequence cmdSeq = dpvm.CreateCommandSequence(); cmdSeq.RegisterCommand(dpvm.ReestablishConnectionCommand); cmdSeq.RegisterCommand(dpvm.RefreshDeviceNameCommand); cmdSeq.RegisterCommand(dpvm.StartListeningForSystemPerfCommand); Loading Loading
Samples/DeviceLab/CommandSequence.cs +87 −11 Original line number Diff line number Diff line Loading @@ -7,21 +7,73 @@ using System.Windows.Input; namespace DeviceLab { public class ObservableCommandQueue { private Queue<ICommand> commands; public ObservableCommandQueue() { this.commands = new Queue<ICommand>(); } public event EventHandler QueueChanged; public int Count { get { return this.commands.Count; } } public void Clear() { this.commands.Clear(); OnQueueChanged(); } public ICommand Peek() { return this.commands.Peek(); } public void Enqueue(ICommand cmd) { this.commands.Enqueue(cmd); OnQueueChanged(); } public ICommand Dequeue() { ICommand cmd = this.commands.Dequeue(); OnQueueChanged(); return cmd; } private void OnQueueChanged() { this.QueueChanged?.Invoke(this, new EventArgs()); } } public class CommandSequence : ICommand { private List<ICommand> registeredCommands; private Queue<ICommand> commandQueue; private ObservableCommandQueue commandQueue; private object sharedParameter; //------------------------------------------------------------------- // Constructor //------------------------------------------------------------------- #region Constructor public CommandSequence(Queue<ICommand> commandQueue = null) public CommandSequence(ObservableCommandQueue commandQueue = null) { this.registeredCommands = new List<ICommand>(); this.commandQueue = commandQueue == null ? new Queue<ICommand>() : commandQueue; this.commandQueue = commandQueue == null ? new ObservableCommandQueue() : commandQueue; this.commandQueue.QueueChanged += CommandQueue_QueueChanged; } #endregion // Constructor //------------------------------------------------------------------- Loading @@ -44,28 +96,48 @@ namespace DeviceLab CommandSequence seq = cmd as CommandSequence; if (seq == null) { this.registeredCommands.Add(cmd); AddCommand(cmd); } else { foreach (ICommand subcmd in seq.registeredCommands) { this.registeredCommands.Add(subcmd); AddCommand(subcmd); } } } OnCanExecuteChanged(); } private void AddCommand(ICommand cmd) { if(this.registeredCommands.Count == 0) { cmd.CanExecuteChanged += Forward_CanExecuteChanged; } this.registeredCommands.Add(cmd); } //------------------------------------------------------------------- // ICommand Implementation //------------------------------------------------------------------- public event EventHandler CanExecuteChanged; private void OnCanExecuteChanged() { this.CanExecuteChanged?.Invoke(this, new EventArgs()); } /// <summary> /// Forward on the CanExecuteChanged event from the first command in the list /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Forward_CanExecuteChanged(object sender, EventArgs e) { this.CanExecuteChanged?.Invoke(sender, e); } public bool CanExecute(object parameter) { if (this.registeredCommands.Count == 0) Loading Loading @@ -106,9 +178,12 @@ namespace DeviceLab private void CurrentCommand_CanExecuteChanged(object sender, EventArgs e) { ICommand cmd = sender as ICommand; if (cmd.CanExecute(this.sharedParameter)) { cmd.CanExecuteChanged -= CurrentCommand_CanExecuteChanged; ExecuteNext(); } } private void ExecuteNext() { Loading @@ -124,11 +199,12 @@ namespace DeviceLab { this.commandQueue.Peek().CanExecuteChanged += CurrentCommand_CanExecuteChanged; } else { OnCanExecuteChanged(); } } private void CommandQueue_QueueChanged(object sender, EventArgs e) { OnCanExecuteChanged(); } } }
Samples/DeviceLab/DeviceLab.csproj +1 −0 Original line number Diff line number Diff line Loading @@ -64,6 +64,7 @@ <Compile Include="DeviceCollectionView.xaml.cs"> <DependentUpon>DeviceCollectionView.xaml</DependentUpon> </Compile> <Compile Include="DevicePortalCommandModel.cs" /> <Compile Include="DevicePortalViewModel.cs" /> <Compile Include="DeviceSignInView.xaml.cs"> <DependentUpon>DeviceSignInView.xaml</DependentUpon> Loading
Samples/DeviceLab/DevicePortalCommandModel.cs 0 → 100644 +81 −0 Original line number Diff line number Diff line using Microsoft.Tools.WindowsDevicePortal; using Prism.Commands; using Prism.Mvvm; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Input; namespace DeviceLab { public class DevicePortalCommandModel : BindableBase { //------------------------------------------------------------------- // Protected Members //------------------------------------------------------------------- #region Protected Members protected IDiagnosticSink diagnostics; protected DevicePortal portal; #endregion // Protected Members //------------------------------------------------------------------- // Constructors //------------------------------------------------------------------- #region Constructors public DevicePortalCommandModel(DevicePortal portal, IDiagnosticSink diags) { this.portal = portal; this.diagnostics = diags; this.commandQueue = new ObservableCommandQueue(); this.Ready = true; } #endregion // Constructors //------------------------------------------------------------------- // Properties //------------------------------------------------------------------- #region Properties /// <summary> /// The Ready property indicates that there are no REST calls in flight via /// the underlying DevicePortal object /// </summary> #region Ready private bool ready; public bool Ready { get { return this.ready; } protected set { SetProperty(ref this.ready, value); } } #endregion // Ready #endregion // Properties //------------------------------------------------------------------- // Command Sequences //------------------------------------------------------------------- #region Command Sequences private ObservableCommandQueue commandQueue; protected void ClearCommandQueue() { this.commandQueue.Clear(); } public CommandSequence CreateCommandSequence() { return new CommandSequence(this.commandQueue); } #endregion // Command Sequences } }
Samples/DeviceLab/DevicePortalViewModel.cs +80 −95 Original line number Diff line number Diff line Loading @@ -12,35 +12,16 @@ using static Microsoft.Tools.WindowsDevicePortal.DevicePortal; namespace DeviceLab { public class DevicePortalViewModel : BindableBase { //------------------------------------------------------------------- // Private Members //------------------------------------------------------------------- #region Private Members private IDiagnosticSink diagnostics; private string diagnosticMoniker public class DevicePortalViewModel : DevicePortalCommandModel { get { return !string.IsNullOrWhiteSpace(this.deviceName) ? this.deviceName : this.Address; } } #endregion // Private Members //------------------------------------------------------------------- // Constructors //------------------------------------------------------------------- #region Constructors public DevicePortalViewModel(DevicePortal portal, IDiagnosticSink diags) : base(portal, diags) { this.ConnectionRetryAttempts = 5; this.diagnostics = diags; this.portal = portal; this.Ready = true; } #endregion // Cosntructors Loading @@ -48,38 +29,15 @@ namespace DeviceLab // Properties //------------------------------------------------------------------- #region Properties #region Portal private DevicePortal portal; private DevicePortal Portal { get { return this.portal; } set { SetProperty(ref this.portal, value); OnPropertyChanged("Address"); OnPropertyChanged("DeviceFamily"); OnPropertyChanged("OperatingSystemVersion"); OnPropertyChanged("Platform"); OnPropertyChanged("PlatformName"); } } #endregion // Portal #region Ready private bool ready; public bool Ready #region Diagnostic Moniker private string diagnosticMoniker { get { return this.ready; } private set { SetProperty(ref this.ready, value); return !string.IsNullOrWhiteSpace(this.deviceName) ? this.deviceName : this.Address; } } #endregion // Ready #endregion // Diagnostic Moniker #region DeviceName private string deviceName; Loading Loading @@ -197,16 +155,20 @@ namespace DeviceLab #region Commands #region RenameCommand private DelegateCommand renameCommand; private CommandSequence renameCommand; public ICommand RenameCommand { get { if(this.renameCommand == null) { this.renameCommand = DelegateCommand.FromAsyncHandler(ExecuteRenameAsync, CanExecuteRename); this.renameCommand.ObservesProperty(() => this.Ready); this.renameCommand.ObservesProperty(() => this.DeviceNameEntry); this.renameCommand = CreateCommandSequence(); DelegateCommand renameDC = DelegateCommand.FromAsyncHandler(ExecuteRenameAsync, CanExecuteRename); renameDC.ObservesProperty(() => this.Ready); renameDC.ObservesProperty(() => this.DeviceNameEntry); this.renameCommand.RegisterCommand(renameDC); this.renameCommand.RegisterCommand(this.RebootCommand); this.renameCommand.RegisterCommand(this.RefreshDeviceNameCommand); } return this.renameCommand; } Loading @@ -214,6 +176,8 @@ namespace DeviceLab private bool CanExecuteRename() { //return // this.Ready; return this.Ready && !string.IsNullOrWhiteSpace(this.deviceNameEntry); Loading @@ -221,42 +185,35 @@ namespace DeviceLab private async Task ExecuteRenameAsync() { this.diagnostics.OutputDiagnosticString("[{0}] ExecuteRenameAsync\n", this.diagnosticMoniker); this.Ready = false; try { string newName = this.deviceNameEntry; this.DeviceNameEntry = ""; this.diagnostics.OutputDiagnosticString("[{0}] Attempting to rename device to {1}\n", this.diagnosticMoniker, newName); await this.Portal.SetDeviceName(newName); await this.portal.SetDeviceName(newName); } catch (Exception exn) { ReportException("Rename", exn); } await ExecuteRebootAsync(); if (this.Ready) { await RefreshDeviceNameAsync(); } else { // TODO: Need to decide what to do if this.Ready == false; // ALTERNATIVLEY: Need to decide how to recover after an error } this.Ready = true; } #endregion // RenameCommand #region RefreshDeviceName private DelegateCommand refreshDeviceNameCommand; private CommandSequence refreshDeviceNameCommand; public ICommand RefreshDeviceNameCommand { get { if(this.refreshDeviceNameCommand == null) { this.refreshDeviceNameCommand = DelegateCommand.FromAsyncHandler(RefreshDeviceNameAsync, CanExecuteRefreshDeviceName); this.refreshDeviceNameCommand.ObservesProperty(() => this.Ready); DelegateCommand refreshDeviceNameDC = DelegateCommand.FromAsyncHandler(RefreshDeviceNameAsync, CanExecuteRefreshDeviceName); refreshDeviceNameDC.ObservesProperty(() => this.Ready); this.refreshDeviceNameCommand = CreateCommandSequence(); this.refreshDeviceNameCommand.RegisterCommand(refreshDeviceNameDC); } return this.refreshDeviceNameCommand; } Loading @@ -269,30 +226,36 @@ namespace DeviceLab private async Task RefreshDeviceNameAsync() { this.diagnostics.OutputDiagnosticString("[{0}] RefreshDeviceNameAsync\n", this.diagnosticMoniker); this.Ready = false; try { this.DeviceName = await this.Portal.GetDeviceName(); this.DeviceName = await this.portal.GetDeviceName(); } catch (Exception exn) { ReportException("RefreshDeviceName", exn); } this.diagnostics.OutputDiagnosticString("[{0}] Retrieved device name.\n", this.diagnosticMoniker); this.Ready = true; } #endregion // RefreshDeviceName #region Reboot Command private DelegateCommand rebootCommand; private CommandSequence rebootCommand; public ICommand RebootCommand { get { if(this.rebootCommand == null) { this.rebootCommand = DelegateCommand.FromAsyncHandler(ExecuteRebootAsync, CanExecuteReboot); this.rebootCommand.ObservesProperty(() => this.Ready); this.rebootCommand = CreateCommandSequence(); DelegateCommand rebootDC = DelegateCommand.FromAsyncHandler(ExecuteRebootAsync, CanExecuteReboot); rebootDC.ObservesProperty(() => this.Ready); this.rebootCommand.RegisterCommand(StopListeningForSystemPerfCommand); this.rebootCommand.RegisterCommand(rebootDC); this.rebootCommand.RegisterCommand(this.ReestablishConnectionCommand); this.rebootCommand.RegisterCommand(this.refreshDeviceNameCommand); this.rebootCommand.RegisterCommand(this.StartListeningForSystemPerfCommand); } return this.rebootCommand; } Loading @@ -305,12 +268,12 @@ namespace DeviceLab private async Task ExecuteRebootAsync() { await ExecuteStopListeningForSystemPerfAsync(); this.diagnostics.OutputDiagnosticString("[{0}] ExecuteRebootAsync\n", this.diagnosticMoniker); this.Ready = false; try { this.diagnostics.OutputDiagnosticString("[{0}] Attempting to reboot device.\n", this.diagnosticMoniker); await this.Portal.Reboot(); await this.portal.Reboot(); // Sometimes able to reestablish the connection prematurely before the console has a chance to shut down // So adding a delay here before trying to reestablish the connection. Loading @@ -320,21 +283,22 @@ namespace DeviceLab { ReportException("Reboot", exn); } await ExecuteReestablishConnectionAsync(); await ExecuteStartListeningForSystemPerfAsync(); this.Ready = true; } #endregion // Reboot Command #region ReestablishConnectionCommand private DelegateCommand reestablishConnectionCommand; private CommandSequence reestablishConnectionCommand; public ICommand ReestablishConnectionCommand { get { if(this.reestablishConnectionCommand == null) { this.reestablishConnectionCommand = DelegateCommand.FromAsyncHandler(ExecuteReestablishConnectionAsync, CanExecuteReestablishConnection); this.reestablishConnectionCommand.ObservesProperty(() => this.Ready); this.reestablishConnectionCommand = CreateCommandSequence(); DelegateCommand reestablishConnectionDC = DelegateCommand.FromAsyncHandler(ExecuteReestablishConnectionAsync, CanExecuteReestablishConnection); reestablishConnectionDC.ObservesProperty(() => this.Ready); this.reestablishConnectionCommand.RegisterCommand(reestablishConnectionDC); } return this.reestablishConnectionCommand; } Loading @@ -347,6 +311,7 @@ namespace DeviceLab private async Task ExecuteReestablishConnectionAsync() { this.diagnostics.OutputDiagnosticString("[{0}] ExecuteReestablishConnectionAsync\n", this.diagnosticMoniker); int numTries = 1; DeviceConnectionStatusEventHandler handler = (DevicePortal sender, DeviceConnectionStatusEventArgs args) => Loading @@ -371,26 +336,28 @@ namespace DeviceLab await this.portal.Connect(); ++numTries; } while (this.portal.ConnectionHttpStatusCode != HttpStatusCode.OK && numTries < this.ConnectionRetryAttempts); this.Ready = true; } catch (Exception exn) { ReportException("ReestablishConnection", exn); } this.portal.ConnectionStatus -= handler; this.Ready = true; } #endregion // ReestablishConnectionCommand #region StartListeningForSystemPerfCommand private DelegateCommand startListeningForSystemPerfCommand; private CommandSequence startListeningForSystemPerfCommand; public ICommand StartListeningForSystemPerfCommand { get { if(this.startListeningForSystemPerfCommand == null) { this.startListeningForSystemPerfCommand = DelegateCommand.FromAsyncHandler(ExecuteStartListeningForSystemPerfAsync, CanStartListeningForSystemPerf); this.startListeningForSystemPerfCommand.ObservesProperty(() => this.Ready); this.startListeningForSystemPerfCommand = CreateCommandSequence(); DelegateCommand startListeningForSystemPerfDC = DelegateCommand.FromAsyncHandler(ExecuteStartListeningForSystemPerfAsync, CanStartListeningForSystemPerf); startListeningForSystemPerfDC.ObservesProperty(() => this.Ready); this.startListeningForSystemPerfCommand.RegisterCommand(startListeningForSystemPerfDC); } return startListeningForSystemPerfCommand; } Loading @@ -403,9 +370,17 @@ namespace DeviceLab private async Task ExecuteStartListeningForSystemPerfAsync() { this.diagnostics.OutputDiagnosticString("[{0}] ExecuteStartListeningForSystemPerfAsync\n", this.diagnosticMoniker); this.Ready = false; try { this.portal.SystemPerfMessageReceived += OnSystemPerfReceived; await Task.Run(StartListeningHelper); } catch(Exception exn) { ReportException("StartListeningForSystemPerf", exn); } this.Ready = true; } Loading @@ -413,19 +388,20 @@ namespace DeviceLab { await this.portal.StartListeningForSystemPerf().ConfigureAwait(false); } #endregion // StartListeningForSystemPerfCommand #region StopListeningForSystemPerfCommand private DelegateCommand stopListeningForSystemPerfCommand; private CommandSequence stopListeningForSystemPerfCommand; public ICommand StopListeningForSystemPerfCommand { get { if(this.stopListeningForSystemPerfCommand == null) { this.stopListeningForSystemPerfCommand = DelegateCommand.FromAsyncHandler(ExecuteStopListeningForSystemPerfAsync, CanStopListeningForSystemPerf); this.stopListeningForSystemPerfCommand.ObservesProperty(() => this.Ready); this.stopListeningForSystemPerfCommand = CreateCommandSequence(); DelegateCommand stopListeningForSystemPerfDC = DelegateCommand.FromAsyncHandler(ExecuteStopListeningForSystemPerfAsync, CanStopListeningForSystemPerf); stopListeningForSystemPerfDC.ObservesProperty(() => this.Ready); this.stopListeningForSystemPerfCommand.RegisterCommand(stopListeningForSystemPerfDC); } return stopListeningForSystemPerfCommand; } Loading @@ -438,11 +414,18 @@ namespace DeviceLab private async Task ExecuteStopListeningForSystemPerfAsync() { this.diagnostics.OutputDiagnosticString("[{0}] ExecuteStopListeningForSystemPerfAsync\n", this.diagnosticMoniker); this.Ready = false; try { this.portal.SystemPerfMessageReceived -= OnSystemPerfReceived; await StopListeningHelper(); //await Task.Run(StopListeningHelper); await StopListeningHelper(); } catch(Exception exn) { ReportException("StopListeningForSystemPerf", exn); } this.Ready = true; } Loading @@ -453,8 +436,6 @@ namespace DeviceLab #endregion // StopListeningForSystemPerfCommand #endregion // Commands private void OnSystemPerfReceived(DevicePortal sender, WebSocketMessageReceivedEventArgs<DevicePortal.SystemPerformanceInformation> args) { this.cpuLoad = args.Message.CpuLoad; Loading @@ -466,6 +447,10 @@ namespace DeviceLab this.diagnostics.OutputDiagnosticString( "[{0}] Exception during {1} command:\n[{0}] {2}\nStackTrace: \n[{0}] {3}\n", this.diagnosticMoniker, commandName, exn.Message, exn.StackTrace); // Clear the command queue to prevent executing any more commands this.diagnostics.OutputDiagnosticString("[{0}] Clearing any queued commands\n", this.diagnosticMoniker); ClearCommandQueue(); } } }
Samples/DeviceLab/MainViewModel.cs +3 −4 Original line number Diff line number Diff line Loading @@ -34,7 +34,6 @@ namespace DeviceLab } #endregion // Constructors private void OnSignInAttemptCompleted(DeviceSignInViewModel sender, DeviceSignInEventArgs args) { DevicePortal portal = args.Portal; Loading Loading @@ -310,7 +309,7 @@ namespace DeviceLab { dpvm.PropertyChanged += DevicePropertyChanged; CommandSequence cmdSeq = new CommandSequence(); CommandSequence cmdSeq = dpvm.CreateCommandSequence(); cmdSeq.RegisterCommand(dpvm.ReestablishConnectionCommand); cmdSeq.RegisterCommand(dpvm.RefreshDeviceNameCommand); cmdSeq.RegisterCommand(dpvm.StartListeningForSystemPerfCommand); Loading