public async Task EnsureNestedCallsAreExcecutedDirectly() { const int NumberOfTasks = 10; var sequencer = new SequencialTaskExecutor(); List <Task> tasks = new List <Task>(); List <int> sequences = new List <int>(); for (int i = 0; i < NumberOfTasks; i++) { int num = i; tasks.Add(sequencer.ExecuteTask(async() => { Func <Task> func = async() => { await sequencer.ExecuteTask(async() => { await Task.Delay(1).ConfigureAwait(false); sequences.Add(num); }); }; await func().ConfigureAwait(false); })); } await Task.WhenAll(tasks.ToArray()); for (int i = 0; i < NumberOfTasks; i++) { Assert.Equal(i, sequences[i]); } }
/// <summary> /// Handles changes to the ProjectDebugger properties. Gets the active profile and generates a launch settings update if it /// has changed. The first evaluation generally kicks off the first snapshot /// </summary> protected async Task ProjectRuleBlock_ChangedAsync(IProjectVersionedValue <IProjectSubscriptionUpdate> projectSubscriptionUpdate) { if (projectSubscriptionUpdate.Value.CurrentState.TryGetValue(ProjectDebugger.SchemaName, out IProjectRuleSnapshot ruleSnapshot)) { ruleSnapshot.Properties.TryGetValue(ProjectDebugger.ActiveDebugProfileProperty, out string activeProfile); var snapshot = CurrentSnapshot; if (snapshot == null || !LaunchProfile.IsSameProfileName(activeProfile, snapshot.ActiveProfile?.Name)) { // Updates need to be sequenced await _sequentialTaskQueue.ExecuteTask(async() => { await UpdateActiveProfileInSnapshotAsync(activeProfile).ConfigureAwait(false); }).ConfigureAwait(false); } } }
public void CalltoDisposedObjectShouldThrow() { var sequencer = new SequencialTaskExecutor(); sequencer.Dispose(); Assert.Throws <ObjectDisposedException>(() => { sequencer.ExecuteTask(() => Task.CompletedTask); }); }
/// <summary> /// Handles changes to the ProjectDebugger properties. Gets the active profile and generates a launch settings update if it /// has changed. The first evaluation generally kicks off the first snapshot /// </summary> protected async Task ProjectRuleBlock_ChangedAsync(IProjectVersionedValue <Tuple <IProjectSubscriptionUpdate, IProjectCapabilitiesSnapshot> > projectSnapshot) { if (projectSnapshot.Value.Item1.CurrentState.TryGetValue(ProjectDebugger.SchemaName, out IProjectRuleSnapshot ruleSnapshot)) { ruleSnapshot.Properties.TryGetValue(ProjectDebugger.ActiveDebugProfileProperty, out string activeProfile); ILaunchSettings snapshot = CurrentSnapshot; if (snapshot == null || !LaunchProfile.IsSameProfileName(activeProfile, snapshot.ActiveProfile?.Name)) { // Updates need to be sequenced await _sequentialTaskQueue.ExecuteTask(async() => { using (ProjectCapabilitiesContext.CreateIsolatedContext(CommonProjectServices.Project, projectSnapshot.Value.Item2)) { await UpdateActiveProfileInSnapshotAsync(activeProfile).ConfigureAwait(false); } }).ConfigureAwait(false); } } }
public async Task EnsureTasksCancelledWhenDisposed() { const int NumberOfTasks = 10; var sequencer = new SequencialTaskExecutor(); List <Task> tasks = new List <Task>(); for (int i = 0; i < NumberOfTasks; i++) { int num = i; tasks.Add(sequencer.ExecuteTask(async() => { Func <Task> func = async() => { await Task.Delay(100).ConfigureAwait(false); }; await func().ConfigureAwait(false); })); } sequencer.Dispose(); try { await Task.WhenAll(tasks.ToArray()); Assert.False(true); } catch (OperationCanceledException) { bool mustBeCancelled = false; for (int i = 0; i < NumberOfTasks; i++) { // The first task or two may already be running. So we skip completed tasks until we find // one that is is cancelled if (mustBeCancelled) { Assert.True(tasks[i].IsCanceled); } else { // All remaining tasks should be cancelled mustBeCancelled = tasks[i].IsCanceled; } } Assert.True(mustBeCancelled); } }