예제 #1
0
        private static void RegisterWorkspaceHost(Workspace workspace, RemoteHostClient client)
        {
            var vsWorkspace = workspace as VisualStudioWorkspaceImpl;

            if (vsWorkspace == null)
            {
                return;
            }

            vsWorkspace.ProjectTracker.RegisterWorkspaceHost(
                new WorkspaceHost(vsWorkspace, client));
        }
예제 #2
0
        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);
            }