public LazyRemoteService(InteractiveHost host, InteractiveHostOptions options, int instanceId, bool skipInitialization)
 {
     InitializedService = new AsyncLazy <InitializedRemoteService>(TryStartAndInitializeProcessAsync, cacheResult: true);
     CancellationSource = new CancellationTokenSource();
     InstanceId         = instanceId;
     Options            = options;
     Host = host;
     SkipInitialization = skipInitialization;
 }
            // Dispose may called anytime, on any thread.
            internal void Dispose()
            {
                // There can be a call from host initiated from OnProcessExit.
                // We should not proceed with disposing if _disposeSemaphore is locked.
                using (_disposeSemaphore.DisposableWait())
                {
                    if (_processExitHandlerStatus == ProcessExitHandlerStatus.Hooked)
                    {
                        Process.Exited           -= ProcessExitedHandler;
                        _processExitHandlerStatus = ProcessExitHandlerStatus.Handled;
                    }
                }

                InitiateTermination(Process, _processId);

                if (_joinOutputWritingThreadsOnDisposal)
                {
                    try
                    {
                        _readOutputThread?.Join();
                    }
                    catch (ThreadStateException)
                    {
                        // thread hasn't started
                    }

                    try
                    {
                        _readErrorOutputThread?.Join();
                    }
                    catch (ThreadStateException)
                    {
                        // thread hasn't started
                    }
                }

                // null the host so that we don't attempt to write to the buffer anymore:
                _host = null;

                _readOutputThread = _readErrorOutputThread = null;
            }
            internal void Dispose(bool joinThreads)
            {
                // There can be a call from host initiated from OnProcessExit.
                // This check on the beginning helps to avoid a reentrancy.
                if (_processExitHandlerStatus == ProcessExitHandlerStatus.Hooked)
                {
                    using (_disposeSemaphore.DisposableWait())
                    {
                        if (_processExitHandlerStatus == ProcessExitHandlerStatus.Hooked)
                        {
                            Process.Exited           -= ProcessExitedHandler;
                            _processExitHandlerStatus = ProcessExitHandlerStatus.Handled;
                        }
                    }
                }

                InitiateTermination(Process, _processId);

                try
                {
                    _readOutputThread?.Join();
                }
                catch (ThreadStateException)
                {
                    // thread hasn't started
                }

                try
                {
                    _readErrorOutputThread?.Join();
                }
                catch (ThreadStateException)
                {
                    // thread hasn't started
                }

                // null the host so that we don't attempt to write to the buffer anymore:
                _host = null;

                _readOutputThread = _readErrorOutputThread = null;
            }
            internal RemoteService(InteractiveHost host, Process process, int processId, JsonRpc jsonRpc)
            {
                Process = process;
                JsonRpc = jsonRpc;

                _host = host;
                _joinOutputWritingThreadsOnDisposal = _host._joinOutputWritingThreadsOnDisposal;
                _processId = processId;
                _processExitHandlerStatus = ProcessExitHandlerStatus.Uninitialized;

                // TODO (tomat): consider using single-thread async readers
                _readOutputThread              = new Thread(() => ReadOutput(error: false));
                _readOutputThread.Name         = "InteractiveHost-OutputReader-" + processId;
                _readOutputThread.IsBackground = true;
                _readOutputThread.Start();

                _readErrorOutputThread              = new Thread(() => ReadOutput(error: true));
                _readErrorOutputThread.Name         = "InteractiveHost-ErrorOutputReader-" + processId;
                _readErrorOutputThread.IsBackground = true;
                _readErrorOutputThread.Start();
            }
Пример #5
0
            internal void Dispose(bool joinThreads)
            {
                // set _disposing so that we don't attempt restart the host anymore:
                _disposing = true;

                InitiateTermination(Process, _processId);

                // only tests require joining the threads, so we can wait synchronously
                if (joinThreads)
                {
                    if (_readOutputThread != null)
                    {
                        try
                        {
                            _readOutputThread.Join();
                        }
                        catch (ThreadStateException)
                        {
                            // thread hasn't started
                        }
                    }

                    if (_readErrorOutputThread != null)
                    {
                        try
                        {
                            _readErrorOutputThread.Join();
                        }
                        catch (ThreadStateException)
                        {
                            // thread hasn't started
                        }
                    }
                }

                // null the host so that we don't attempt to write to the buffer anymore:
                _host = null;

                _readOutputThread = _readErrorOutputThread = null;
            }
Пример #6
0
            private InteractiveHost _host;         // nulled on dispose

            internal RemoteService(InteractiveHost host, Process process, int processId, Service service)
            {
                Debug.Assert(host != null);
                Debug.Assert(process != null);
                Debug.Assert(service != null);

                _host        = host;
                this.Process = process;
                _processId   = processId;
                this.Service = service;

                // TODO (tomat): consider using single-thread async readers
                _readOutputThread              = new Thread(() => ReadOutput(error: false));
                _readOutputThread.Name         = "InteractiveHost-OutputReader-" + processId;
                _readOutputThread.IsBackground = true;
                _readOutputThread.Start();

                _readErrorOutputThread              = new Thread(() => ReadOutput(error: true));
                _readErrorOutputThread.Name         = "InteractiveHost-ErrorOutputReader-" + processId;
                _readErrorOutputThread.IsBackground = true;
                _readErrorOutputThread.Start();
            }