public async Task Queue_ProcessesNotifications_AndGoesBackToSleep() { // Arrange var projectManager = new TestProjectSnapshotManager(Dispatcher, Workspace); var projectWorker = new TestProjectSnapshotWorker(); var queue = new ProjectSnapshotWorkerQueue(Dispatcher, projectManager, projectWorker) { Delay = TimeSpan.FromMilliseconds(1), BlockBackgroundWorkStart = new ManualResetEventSlim(initialState: false), NotifyBackgroundWorkFinish = new ManualResetEventSlim(initialState: false), NotifyForegroundWorkFinish = new ManualResetEventSlim(initialState: false), }; // Act & Assert queue.Enqueue(Project1); Assert.True(queue.IsScheduledOrRunning); Assert.True(queue.HasPendingNotifications); // Allow the background work to proceed. queue.BlockBackgroundWorkStart.Set(); // Get off the foreground thread and allow the updates to flow through. await Task.Run(() => queue.NotifyForegroundWorkFinish.Wait(TimeSpan.FromSeconds(1))); Assert.False(queue.IsScheduledOrRunning); Assert.False(queue.HasPendingNotifications); }
public async Task Queue_ProcessesNotifications_AndGoesBackToSleep() { // Arrange var projectManager = new TestProjectSnapshotManager(Dispatcher, Workspace); projectManager.HostProjectAdded(HostProject1); projectManager.HostProjectAdded(HostProject2); projectManager.WorkspaceProjectAdded(WorkspaceProject1); projectManager.WorkspaceProjectAdded(WorkspaceProject2); var projectWorker = new TestProjectSnapshotWorker(); var queue = new ProjectSnapshotWorkerQueue(Dispatcher, projectManager, projectWorker) { Delay = TimeSpan.FromMilliseconds(1), BlockBackgroundWorkStart = new ManualResetEventSlim(initialState: false), NotifyBackgroundWorkFinish = new ManualResetEventSlim(initialState: false), NotifyForegroundWorkFinish = new ManualResetEventSlim(initialState: false), }; // Act & Assert queue.Enqueue(projectManager.GetSnapshot(HostProject1).CreateUpdateContext()); Assert.True(queue.IsScheduledOrRunning, "Queue should be scheduled during Enqueue"); Assert.True(queue.HasPendingNotifications, "Queue should have a notification created during Enqueue"); // Allow the background work to proceed. queue.BlockBackgroundWorkStart.Set(); // Get off the foreground thread and allow the updates to flow through. await Task.Run(() => queue.NotifyForegroundWorkFinish.Wait(TimeSpan.FromSeconds(1))); Assert.False(queue.IsScheduledOrRunning, "Queue should not have restarted"); Assert.False(queue.HasPendingNotifications, "Queue should have processed all notifications"); }
public async Task Queue_ProcessesNotifications_AndRestarts() { // Arrange var projectManager = new TestProjectSnapshotManager(Dispatcher, Workspace); var projectWorker = new TestProjectSnapshotWorker(); var queue = new ProjectSnapshotWorkerQueue(Dispatcher, projectManager, projectWorker) { Delay = TimeSpan.FromMilliseconds(1), BlockBackgroundWorkStart = new ManualResetEventSlim(initialState: false), NotifyBackgroundWorkFinish = new ManualResetEventSlim(initialState: false), NotifyForegroundWorkFinish = new ManualResetEventSlim(initialState: false), }; // Act & Assert queue.Enqueue(Project1); Assert.True(queue.IsScheduledOrRunning); Assert.True(queue.HasPendingNotifications); // Allow the background work to proceed. queue.BlockBackgroundWorkStart.Set(); queue.NotifyBackgroundWorkFinish.Wait(); // Block the foreground thread so we can queue another notification. Assert.True(queue.IsScheduledOrRunning); Assert.False(queue.HasPendingNotifications); queue.Enqueue(Project2); Assert.True(queue.HasPendingNotifications); // Now we should see the worker restart when it finishes. // Get off the foreground thread and allow the updates to flow through. await Task.Run(() => queue.NotifyForegroundWorkFinish.Wait(TimeSpan.FromSeconds(1))); queue.NotifyBackgroundWorkFinish.Reset(); queue.NotifyForegroundWorkFinish.Reset(); // It should start running again right away. Assert.True(queue.IsScheduledOrRunning); Assert.True(queue.HasPendingNotifications); // Allow the background work to proceed. queue.BlockBackgroundWorkStart.Set(); // Get off the foreground thread and allow the updates to flow through. await Task.Run(() => queue.NotifyForegroundWorkFinish.Wait(TimeSpan.FromSeconds(1))); Assert.False(queue.IsScheduledOrRunning); Assert.False(queue.HasPendingNotifications); }
public DefaultProjectSnapshotManager( ForegroundDispatcher foregroundDispatcher, ErrorReporter errorReporter, ProjectSnapshotWorker worker, IEnumerable <ProjectSnapshotChangeTrigger> triggers, Workspace workspace) { if (foregroundDispatcher == null) { throw new ArgumentNullException(nameof(foregroundDispatcher)); } if (errorReporter == null) { throw new ArgumentNullException(nameof(errorReporter)); } if (worker == null) { throw new ArgumentNullException(nameof(worker)); } if (triggers == null) { throw new ArgumentNullException(nameof(triggers)); } if (workspace == null) { throw new ArgumentNullException(nameof(workspace)); } _foregroundDispatcher = foregroundDispatcher; _errorReporter = errorReporter; _worker = worker; _triggers = triggers.ToArray(); Workspace = workspace; _projects = new Dictionary <string, DefaultProjectSnapshot>(FilePathComparer.Instance); _workerQueue = new ProjectSnapshotWorkerQueue(_foregroundDispatcher, this, worker); for (var i = 0; i < _triggers.Length; i++) { _triggers[i].Initialize(this); } }