private static void RegisterWorkspaceHost(Workspace workspace, RemoteHostClient client) { var vsWorkspace = workspace as VisualStudioWorkspaceImpl; if (vsWorkspace == null) { return; } vsWorkspace.ProjectTracker.RegisterWorkspaceHost( new WorkspaceHost(vsWorkspace, client)); }
private static Task RegisterWorkspaceHostAsync(Workspace workspace, RemoteHostClient client) { var vsWorkspace = workspace as VisualStudioWorkspaceImpl; if (vsWorkspace == null) { return(Task.CompletedTask); } // RegisterWorkspaceHost is required to be called from UI thread so push the code // to UI thread to run. return(Task.Factory.SafeStartNew(() => { vsWorkspace.ProjectTracker.RegisterWorkspaceHost(new WorkspaceHost(vsWorkspace, client)); }, CancellationToken.None, ForegroundThreadAffinitizedObject.CurrentForegroundThreadData.TaskScheduler)); }
public void Disable() { RemoteHostClient client = null; lock (_gate) { if (_remoteClientTask == null) { // already disabled return; } var remoteClientTask = _remoteClientTask; _remoteClientTask = null; RemoveGlobalAssets(); _shutdownCancellationTokenSource.Cancel(); _checksumUpdater.Shutdown(); _checksumUpdater = null; try { remoteClientTask.Wait(_shutdownCancellationTokenSource.Token); // result can be null if service hub failed to launch client = remoteClientTask.Result; } catch (OperationCanceledException) { // remoteClientTask wasn't finished running yet. } } if (client != null) { client.StatusChanged -= OnStatusChanged; // shut it down outside of lock so that // we don't call into different component while // holding onto a lock client.Shutdown(); } }
private static async Task RegisterWorkspaceHostAsync(Workspace workspace, RemoteHostClient client) { var vsWorkspace = workspace as VisualStudioWorkspaceImpl; if (vsWorkspace == null) { return; } // don't block UI thread while initialize workspace host var host = new WorkspaceHost(vsWorkspace, client); await host.InitializeAsync().ConfigureAwait(false); // RegisterWorkspaceHost is required to be called from UI thread so push the code // to UI thread to run. await Task.Factory.SafeStartNew(() => { vsWorkspace.GetProjectTrackerAndInitializeIfNecessary(Shell.ServiceProvider.GlobalProvider).RegisterWorkspaceHost(host); }, CancellationToken.None, ForegroundThreadAffinitizedObject.CurrentForegroundThreadData.TaskScheduler).ConfigureAwait(false); }
private void PushTextChanges(Document oldDocument, Document newDocument) { // this pushes text changes to the remote side if it can. // this is purely perf optimization. whether this pushing text change // worked or not doesn't affect feature's functionality. // // this basically see whether it can cheaply find out text changes // between 2 snapshots, if it can, it will send out that text changes to // remote side. // // the remote side, once got the text change, will again see whether // it can use that text change information without any high cost and // create new snapshot from it. // // otherwise, it will do the normal behavior of getting full text from // VS side. this optimization saves times we need to do full text // synchronization for typing scenario. if ((oldDocument.TryGetText(out var oldText) == false) || (newDocument.TryGetText(out var newText) == false)) { // we only support case where text already exist return; } // get text changes var textChanges = newText.GetTextChanges(oldText); if (textChanges.Count == 0) { // no changes return; } // whole document case if (textChanges.Count == 1 && textChanges[0].Span.Length == oldText.Length) { // no benefit here. pulling from remote host is more efficient return; } // only cancelled when remote host gets shutdown var token = Listener.BeginAsyncOperation(nameof(PushTextChanges)); _textChangeQueue.ScheduleTask(async() => { var client = await RemoteHostClient.TryGetClientAsync(_service.Workspace, CancellationToken).ConfigureAwait(false); if (client == null) { return; } var state = await oldDocument.State.GetStateChecksumsAsync(CancellationToken).ConfigureAwait(false); _ = await client.TryRunRemoteAsync( WellKnownRemoteHostServices.RemoteHostService, nameof(IRemoteHostService.SynchronizeTextAsync), solution: null, new object[] { oldDocument.Id, state.Text, textChanges }, callbackTarget: null, CancellationToken).ConfigureAwait(false); }, CancellationToken).CompletesAsyncOperation(token); }