private async Task AddWriteTaskAsync <TKey>( MultiDictionary <TKey, Action <SqlConnection> > queue, TKey key, Action <SqlConnection> action, CancellationToken cancellationToken) { using (await _writeQueueGate.DisposableWaitAsync(cancellationToken).ConfigureAwait(false)) { queue.Add(key, action); // If we don't have an outstanding request to write the queue to the DB // then create one to run a short while from now. If there is an outstanding // request, then it will see this write request when it runs. if (_flushAllTask == null) { var token = _shutdownTokenSource.Token; _flushAllTask = Task.Delay(FlushAllDelayMS, token) .ContinueWith( async _ => await FlushAllPendingWritesAsync(token).ConfigureAwait(false), token, TaskContinuationOptions.None, TaskScheduler.Default); } } }
private async void OnConnectionChanged(object sender, bool connected) { if (connected) { return; } // to make things simpler, this is not cancellable. I believe this // is okay since this handle rare cases where remote host is recycled or // removed using (await _gate.DisposableWaitAsync(CancellationToken.None).ConfigureAwait(false)) { _client.ConnectionChanged -= OnConnectionChanged; _sessionDoNotAccessDirectly?.Dispose(); _sessionDoNotAccessDirectly = null; _client = await _workspace.TryGetRemoteHostClientAsync(CancellationToken.None).ConfigureAwait(false); if (_client != null) { // client can be null if host is shutting down _client.ConnectionChanged += OnConnectionChanged; } } }
public async Task SynchronizeAssetsAsync(IEnumerable <Checksum> checksums, CancellationToken cancellationToken) { using (await s_gate.DisposableWaitAsync(cancellationToken).ConfigureAwait(false)) { await SynchronizeAssets_NoLockAsync(checksums, cancellationToken).ConfigureAwait(false); } }
public override async ValueTask OnDefinitionFoundAsync(DefinitionItem definition) { using (await _semaphore.DisposableWaitAsync(CancellationToken).ConfigureAwait(false)) { if (_definitionToId.ContainsKey(definition)) { return; } // Assigning a new id to the definition _id++; _definitionToId.Add(definition, _id); // Creating a new VSReferenceItem for the definition var definitionItem = await GenerateVSReferenceItemAsync( _id, definitionId : _id, _document, _position, definition.SourceSpans.FirstOrDefault(), definition.DisplayableProperties, _metadataAsSourceFileService, definition.GetClassifiedText(), definition.Tags.GetFirstGlyph(), symbolUsageInfo : null, isWrittenTo : false, CancellationToken).ConfigureAwait(false); if (definitionItem != null) { // If a definition shouldn't be included in the results list if it doesn't have references, we // have to hold off on reporting it until later when we do find a reference. if (definition.DisplayIfNoReferences) { _workQueue.AddWork(definitionItem); } else { _definitionsWithoutReference.Add(definitionItem.Id, definitionItem); } } } }
public async Task UpdateCacheAsync( Uri uri, LSP.SemanticTokens tokens, CancellationToken cancellationToken) { Contract.ThrowIfNull(tokens.ResultId); using (await _semaphore.DisposableWaitAsync(cancellationToken).ConfigureAwait(false)) { // Case 1: Document does not currently have any token sets cached. Create a cache // for the document and return. if (!_tokens.TryGetValue(uri, out var tokenSets)) { _tokens.Add(uri, new List <LSP.SemanticTokens> { tokens }); return; } // Case 2: Document already has the maximum number of token sets cached. Remove the // oldest token set from the cache, and then add the new token set (see case 3). if (tokenSets.Count >= _maxCachesPerDoc) { tokenSets.RemoveAt(0); } // Case 3: Document has less than the maximum number of token sets cached. // Add new token set to cache. tokenSets.Add(tokens); } }
private async Task <Solution> GetSolutionInternalAsync( Checksum solutionChecksum, bool fromPrimaryBranch, int workspaceVersion, CancellationToken cancellationToken) { var currentSolution = GetAvailableSolution(solutionChecksum); if (currentSolution != null) { return(currentSolution); } // make sure there is always only one that creates a new solution using (await s_gate.DisposableWaitAsync(cancellationToken).ConfigureAwait(false)) { currentSolution = GetAvailableSolution(solutionChecksum); if (currentSolution != null) { return(currentSolution); } var solution = await CreateSolution_NoLockAsync( solutionChecksum, fromPrimaryBranch, workspaceVersion, PrimaryWorkspace.CurrentSolution, cancellationToken).ConfigureAwait(false); s_lastSolution = Tuple.Create(solutionChecksum, solution); return(solution); } }
public async Task <Solution> GetSolutionAsync(Checksum solutionChecksum, CancellationToken cancellationToken) { var currentSolution = s_primaryWorkspace.CurrentSolution; var primarySolutionChecksum = await currentSolution.State.GetChecksumAsync(cancellationToken).ConfigureAwait(false); if (primarySolutionChecksum == solutionChecksum) { // nothing changed return(currentSolution); } var lastSolution = s_lastSolution; if (lastSolution?.Item1 == solutionChecksum) { return(lastSolution.Item2); } // make sure there is always only one that creates a new solution using (await s_gate.DisposableWaitAsync(cancellationToken).ConfigureAwait(false)) { if (s_lastSolution?.Item1 == solutionChecksum) { return(s_lastSolution.Item2); } var solution = await CreateSolution_NoLockAsync(solutionChecksum, currentSolution, cancellationToken).ConfigureAwait(false); s_lastSolution = Tuple.Create(solutionChecksum, solution); return(solution); } }
public async Task OnCompilationEventsGeneratedAsync(ImmutableArray <CompilationEvent> compilationEvents, AnalyzerDriver driver, CancellationToken cancellationToken) { await EnsureAnalyzerActionCountsInitializedAsync(driver, cancellationToken).ConfigureAwait(false); using (await _gate.DisposableWaitAsync(cancellationToken).ConfigureAwait(false)) { await OnCompilationEventsGenerated_NoLockAsync(compilationEvents, driver, cancellationToken).ConfigureAwait(false); } }
public async Task SynchronizeAssetsAsync(IEnumerable <Checksum> checksums, CancellationToken cancellationToken) { using (await s_gate.DisposableWaitAsync(cancellationToken).ConfigureAwait(false)) using (var pooledObject = SharedPools.Default <HashSet <Checksum> >().GetPooledObject()) { AddIfNeeded(pooledObject.Object, checksums); await _assetService.SynchronizeAssetsAsync(pooledObject.Object, cancellationToken).ConfigureAwait(false); } }
/// <summary> /// Ensures that <see cref="_currentAggregateProjectContext"/> is updated for the latest TargetFrameworks from the project properties /// and returns this value. /// </summary> private async Task <AggregateWorkspaceProjectContext> UpdateProjectContextAsync() { // Ensure that only single thread is attempting to create a project context. AggregateWorkspaceProjectContext previousContextToDispose = null; using (await _gate.DisposableWaitAsync().ConfigureAwait(false)) { // Check if we have already computed the project context. if (_currentAggregateProjectContext != null) { // For non-cross targeting projects, we can use the current project context. // For cross-targeting projects, we need to verify that the TargetFrameworks for the current project context matches latest TargetFrameworks project property value. // If not, we create a new one and dispose the current one. if (!_currentAggregateProjectContext.IsCrossTargeting) { return(_currentAggregateProjectContext); } var projectProperties = await _commonServices.ActiveConfiguredProjectProperties.GetConfigurationGeneralPropertiesAsync().ConfigureAwait(false); var targetFrameworks = (string)await projectProperties.TargetFrameworks.GetValueAsync().ConfigureAwait(false); if (_currentAggregateProjectContext.HasMatchingTargetFrameworks(targetFrameworks)) { return(_currentAggregateProjectContext); } previousContextToDispose = _currentAggregateProjectContext; } // Force refresh the CPS active project configuration (needs UI thread). await _commonServices.ThreadingService.SwitchToUIThread(); await _activeProjectConfigurationRefreshService.RefreshActiveProjectConfigurationAsync().ConfigureAwait(false); // Create new project context. _currentAggregateProjectContext = await _contextProvider.Value.CreateProjectContextAsync().ConfigureAwait(false); // Dispose the old project context, if one exists. if (previousContextToDispose != null) { await _contextProvider.Value.ReleaseProjectContextAsync(previousContextToDispose).ConfigureAwait(false); foreach (var innerContext in previousContextToDispose.DisposedInnerProjectContexts) { foreach (var handler in Handlers) { await handler.Value.OnContextReleasedAsync(innerContext).ConfigureAwait(false); } } } return(_currentAggregateProjectContext); } }
private async Task <Compilation> GetOrBuildDeclarationCompilationAsync(SolutionState solution, CancellationToken cancellationToken) { try { cancellationToken.ThrowIfCancellationRequested(); using (await _buildLock.DisposableWaitAsync(cancellationToken).ConfigureAwait(false)) { var state = this.ReadState(); // we are already in the final stage. just return it. var compilation = state.FinalCompilation.GetValue(cancellationToken); if (compilation != null) { return(compilation); } compilation = state.Compilation.GetValue(cancellationToken); if (compilation == null) { // let's see whether we have declaration only compilation if (state.DeclarationOnlyCompilation != null) { // okay, move to full declaration state. do this so that declaration only compilation never // realize symbols. var declarationOnlyCompilation = state.DeclarationOnlyCompilation.Clone(); this.WriteState(new FullDeclarationState(declarationOnlyCompilation), solution); return(declarationOnlyCompilation); } // We've got nothing. Build it from scratch :( return(await BuildDeclarationCompilationFromScratchAsync(solution, cancellationToken).ConfigureAwait(false)); } else if (state is FullDeclarationState) { // we have full declaration, just use it. return(state.Compilation.GetValue(cancellationToken)); } else if (state is InProgressState inProgress) { // We have an in progress compilation. Build off of that. return(await BuildDeclarationCompilationFromInProgressAsync(solution, inProgress, compilation, cancellationToken).ConfigureAwait(false)); } else { throw ExceptionUtilities.Unreachable; } } } catch (Exception e) when(FatalError.ReportUnlessCanceled(e)) { throw ExceptionUtilities.Unreachable; } }
private JoinableTask <T> ExecuteWithinLockAsync <T>(Func <Task <T> > task) { // We need to request the lock within a joinable task to ensure that if we are blocking the UI // thread (i.e. when CPS is draining critical tasks on the UI thread and is waiting on this task), // and the lock is already held by another task requesting UI thread access, we don't reach a deadlock. return(JoinableFactory.RunAsync(async delegate { using (JoinableCollection.Join()) using (await _gate.DisposableWaitAsync().ConfigureAwait(false)) { return await task().ConfigureAwait(false); } })); }
public async Task <bool> HasPendingSyntaxAnalysisAsync(SyntaxTree treeOpt, CancellationToken cancellationToken) { using (await _gate.DisposableWaitAsync(cancellationToken).ConfigureAwait(false)) { return(_lazyPendingSyntaxAnalysisTrees != null && (treeOpt != null ? _lazyPendingSyntaxAnalysisTrees.ContainsKey(treeOpt) : _lazyPendingSyntaxAnalysisTrees.Count > 0)); } }
public async Task <bool> TryInvokeAsync(string targetName, IReadOnlyList <object> arguments, CancellationToken cancellationToken) { using (await _gate.DisposableWaitAsync(cancellationToken).ConfigureAwait(false)) { var connection = await TryGetConnection_NoLockAsync(cancellationToken).ConfigureAwait(false); if (connection == null) { return(false); } await connection.InvokeAsync(targetName, arguments, cancellationToken).ConfigureAwait(false); return(true); } }
/// <summary> /// Retrieves the base folder paths for files on the client that have been retrieved from the remote host. /// Triggers a refresh of all open files so we make sure they are in the correct workspace. /// </summary> private async Task UpdatePathsToRemoteFilesAsync(CollaborationSession session) { var(remoteRootPaths, externalPaths) = await GetLocalPathsOfRemoteRootsAsync(session) .ConfigureAwait(false); // Make sure we update our references to the remote roots and iterate RDT only one at a time. using ( await s_RemotePathsGate .DisposableWaitAsync(CancellationToken.None) .ConfigureAwait(false) ) { if ( IsRemoteSession && ( !_remoteWorkspaceRootPaths.Equals(remoteRootPaths) || !_registeredExternalPaths.Equals(externalPaths) ) ) { _remoteWorkspaceRootPaths = remoteRootPaths; _registeredExternalPaths = externalPaths; await RefreshAllFilesAsync().ConfigureAwait(false); } } }
public async Task <bool> TryInvokeAsync(string targetName, params object[] arguments) { using (await _gate.DisposableWaitAsync(_cancellationToken).ConfigureAwait(false)) { var connection = await TryGetConnection_NoLockAsync().ConfigureAwait(false); if (connection == null) { return(false); } await connection.InvokeAsync(targetName, arguments).ConfigureAwait(false); return(true); } }
private async Task ProcessExitedHandlerAsync() { try { using (await _disposeSemaphore.DisposableWaitAsync().ConfigureAwait(false)) { if (_processExitHandlerStatus == ProcessExitHandlerStatus.Hooked) { Process.Exited -= ProcessExitedHandler; _processExitHandlerStatus = ProcessExitHandlerStatus.Handled; // Should set _processExitHandlerStatus before calling OnProcessExited to avoid deadlocks. // Calling the host should be within the lock to prevent its disposing during the execution. } } var host = _host; if (host != null) { await host.OnProcessExited(Process).ConfigureAwait(false); } } catch (Exception e) when(FatalError.Report(e)) { throw ExceptionUtilities.Unreachable; } }
public async Task <WebClientResult> Get(string url, int retryCount = 10) { Task <string> MakeRequest() { _webClient.Headers["User-Agent"] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:58.0) Gecko/20100101 Firefox/58.0"; var result = _webClient.DownloadString(new Uri(url)); return(Task.FromResult(result)); } using (await _semaphoreSlim.DisposableWaitAsync(TimeSpan.FromMinutes(10))) { return(await RetryableRequest(MakeRequest, retryCount)); } }
private async Task <ISymbolSearchUpdateEngine> GetEngineAsync(CancellationToken cancellationToken) { using (await _gate.DisposableWaitAsync(cancellationToken).ConfigureAwait(false)) { return(_lazyUpdateEngine ??= await SymbolSearchUpdateEngineFactory.CreateEngineAsync( _workspace, _logService, _progressService, cancellationToken).ConfigureAwait(false)); } }
private async Task <MSB.Execution.BuildResult> BuildAsync(MSB.Execution.BuildRequestData requestData, CancellationToken cancellationToken) { // only allow one build to use the default build manager at a time using (await s_buildManagerLock.DisposableWaitAsync(cancellationToken).ConfigureAwait(false)) { return(await BuildAsync(MSB.Execution.BuildManager.DefaultBuildManager, requestData, cancellationToken).ConfigureAwait(false)); } }
public async Task UpdatePrimaryBranchSolutionAsync(AssetProvider assetProvider, Checksum solutionChecksum, int workspaceVersion, CancellationToken cancellationToken) { var currentSolution = CurrentSolution; var currentSolutionChecksum = await currentSolution.State.GetChecksumAsync(cancellationToken).ConfigureAwait(false); if (currentSolutionChecksum == solutionChecksum) { return; } using (await _availableSolutionsGate.DisposableWaitAsync(cancellationToken).ConfigureAwait(false)) { var solution = await CreateSolution_NoLockAsync(assetProvider, solutionChecksum, fromPrimaryBranch : true, workspaceVersion, currentSolution, cancellationToken).ConfigureAwait(false); _primaryBranchSolutionWithChecksum = Tuple.Create(solutionChecksum, solution); } }
private async Task <KeepAliveSession> TryGetKeepAliveSessionAsync(RemoteHostClient client, CancellationToken cancellationToken) { using (await _gate.DisposableWaitAsync(cancellationToken).ConfigureAwait(false)) { if (_sessionDoNotAccessDirectly == null) { _sessionDoNotAccessDirectly = await client.TryCreateCodeAnalysisKeepAliveSessionAsync(cancellationToken).ConfigureAwait(false); } return(_sessionDoNotAccessDirectly); } }
private async Task <ISymbolSearchUpdateEngine> GetEngine(CancellationToken cancellationToken) { using (await _gate.DisposableWaitAsync(cancellationToken).ConfigureAwait(false)) { if (_updateEngine == null) { _updateEngine = await SymbolSearchUpdateEngineFactory.CreateEngineAsync( _workspace, _logService, cancellationToken).ConfigureAwait(false); } return(_updateEngine); } }
private static async Task <bool> DelayAsync(SemaphoreSlim semaphoreSlim) { await Task.Delay(1000); var random = new Random(); using (await semaphoreSlim.DisposableWaitAsync(TimeSpan.MaxValue)) { await Task.Delay(random.Next(1, 100)); return(true); } }
public static async Task ExecuteWithinLockAsync(this SemaphoreSlim semaphore, JoinableTaskCollection collection, JoinableTaskFactory factory, Action action) { // Join the caller to our collection, so that if the lock is already held by another task that needs UI // thread access we don't deadlock if we're also being waited on by the UI thread. For example, when CPS // is draining critical tasks and is waiting us. using (collection.Join()) { using (await semaphore.DisposableWaitAsync().ConfigureAwait(false)) { action(); } } }
public override async Task OnDefinitionFoundAsync(DefinitionItem definition) { using (await _semaphore.DisposableWaitAsync(CancellationToken).ConfigureAwait(false)) { if (_definitionToId.ContainsKey(definition)) { return; } // Assigning a new id to the definition _id++; _definitionToId.Add(definition, _id); // VSReferenceItem currently doesn't support the ClassifiedTextElement type for DefinitionText, // so for now we just pass in a string. // https://devdiv.visualstudio.com/DevDiv/_workitems/edit/918138 var classifiedText = definition.GetClassifiedText(); using var pd = PooledStringBuilder.GetInstance(out var pooledBuilder); foreach (var text in classifiedText.Runs) { pooledBuilder.Append(text.Text); } var definitionText = pooledBuilder.ToString(); // Creating a new VSReferenceItem for the definition var definitionItem = await GenerateVSReferenceItemAsync( _id, definitionId : _id, _document, _position, definition.SourceSpans.FirstOrDefault(), definition.DisplayableProperties, _metadataAsSourceFileService, definitionText, symbolUsageInfo : null, CancellationToken).ConfigureAwait(false); if (definitionItem != null) { AddToReferencesToReport_MustBeCalledUnderLock(definitionItem); } } }
private async Task <KeepAliveSession> TryGetKeepAliveSessionAsync(RemoteHostClient client, CancellationToken cancellation) { using (await _gate.DisposableWaitAsync(cancellation).ConfigureAwait(false)) { if (_sessionDoNotAccessDirectly == null) { // we give cancellation none here since the cancellation will cause KeepAlive session to be shutdown // when raised _sessionDoNotAccessDirectly = await client.TryCreateCodeAnalysisKeepAliveSessionAsync(CancellationToken.None).ConfigureAwait(false); } return(_sessionDoNotAccessDirectly); } }
private async Task UpdateSolutionChecksumAsync(CancellationToken cancellationToken) { using (await _gate.DisposableWaitAsync(cancellationToken).ConfigureAwait(false)) { // hold onto previous snapshot var previousSnapshot = _lastSnapshot; // create a new one (incrementally update the snapshot) _lastSnapshot = await _checksumService.CreateChecksumAsync(_service.Workspace.CurrentSolution, cancellationToken).ConfigureAwait(false); // let old one go. previousSnapshot?.Dispose(); } }
private async Task UpdateSeriesIfNecessaryAsync(TvDbSeries series) { bool ownsTask = false; Task update = null; using (await ioLock.DisposableWaitAsync()) { if (updates.ContainsKey(series)) { update = updates[series]; } var needsUpdating = (series.Updated == null) || (DateTime.Now - series.Updated > TimeSpan.FromHours(3)); if (needsUpdating) { update = UpdateSeriesAsync(series); updates.Add(series, update); ownsTask = true; } } if (update != null) { await update; if (ownsTask) { using (await ioLock.DisposableWaitAsync()) { updates.Remove(series); if (series.IsSubscribed) { storageManager.Save(series); } } } } }
// More complicated forwarding functions. These need to map from the symbols // used by the FAR engine to the INavigableItems used by the streaming FAR // feature. private async Task <DefinitionItem> GetDefinitionItemAsync(SymbolAndProjectId definition) { using (await _gate.DisposableWaitAsync(_context.CancellationToken).ConfigureAwait(false)) { if (!_definitionToItem.TryGetValue(definition.Symbol, out var definitionItem)) { definitionItem = await definition.Symbol.ToClassifiedDefinitionItemAsync( _solution.GetProject(definition.ProjectId), includeHiddenLocations : false, cancellationToken : _context.CancellationToken).ConfigureAwait(false); _definitionToItem[definition.Symbol] = definitionItem; } return(definitionItem); } }