Ejemplo n.º 1
0
        /// <summary>
        /// Restarts and reinitializes the host process (or starts a new one if it is not running yet).
        /// </summary>
        /// <param name="optionsOpt">The options to initialize the new process with, or null to use the current options (or default options if the process isn't running yet).</param>
        public async Task <RemoteExecutionResult> ResetAsync(InteractiveHostOptions optionsOpt)
        {
            try
            {
                var options = optionsOpt ?? _lazyRemoteService?.Options ?? new InteractiveHostOptions(null, CultureInfo.CurrentUICulture);

                // replace the existing service with a new one:
                var newService = CreateRemoteService(options, skipInitialization: false);

                LazyRemoteService oldService = Interlocked.Exchange(ref _lazyRemoteService, newService);
                if (oldService != null)
                {
                    oldService.Dispose(joinThreads: false);
                }

                var initializedService = await TryGetOrCreateRemoteServiceAsync(processPendingOutput : false).ConfigureAwait(false);

                if (initializedService.ServiceOpt == null)
                {
                    return(default(RemoteExecutionResult));
                }

                return(initializedService.InitializationResult);
            }
            catch (Exception e) when(FatalError.Report(e))
            {
                throw ExceptionUtilities.Unreachable;
            }
        }
Ejemplo n.º 2
0
 private void DisposeRemoteService(bool disposing)
 {
     if (_lazyRemoteService != null)
     {
         _lazyRemoteService.Dispose(disposing);
         _lazyRemoteService = null;
     }
 }
Ejemplo n.º 3
0
        public async Task ResetAsync()
        {
            // replace the existing service with a new one:
            var newService = new LazyRemoteService(this);
            var oldService = Interlocked.Exchange(ref _lazyRemoteService, newService);

            oldService?.Dispose();
            await TryGetOrCreateRemoteServiceAsync().ConfigureAwait(false);
        }
Ejemplo n.º 4
0
        private async Task <InitializedRemoteService> TryGetOrCreateRemoteServiceAsync(bool processPendingOutput)
        {
            try
            {
                LazyRemoteService currentRemoteService = _lazyRemoteService;

                for (int attempt = 0; attempt < MaxAttemptsToCreateProcess; attempt++)
                {
                    // Remote service may be disposed anytime.
                    if (currentRemoteService == null)
                    {
                        return(default);
Ejemplo n.º 5
0
        private async Task <InitializedRemoteService> TryGetOrCreateRemoteServiceAsync(bool processPendingOutput)
        {
            try
            {
                LazyRemoteService currentRemoteService = _lazyRemoteService;

                // disposed or not reset:
                Debug.Assert(currentRemoteService != null);

                for (int attempt = 0; attempt < MaxAttemptsToCreateProcess; attempt++)
                {
                    var initializedService = await currentRemoteService.InitializedService.GetValueAsync(currentRemoteService.CancellationSource.Token).ConfigureAwait(false);

                    if (initializedService.ServiceOpt != null && initializedService.ServiceOpt.Process.IsAlive())
                    {
                        return(initializedService);
                    }

                    // Service failed to start or initialize or the process died.
                    var newService = CreateRemoteService(currentRemoteService.Options, skipInitialization: !initializedService.InitializationResult.Success);

                    var previousService = Interlocked.CompareExchange(ref _lazyRemoteService, newService, currentRemoteService);
                    if (previousService == currentRemoteService)
                    {
                        // we replaced the service whose process we know is dead:
                        currentRemoteService.Dispose(processPendingOutput);
                        currentRemoteService = newService;
                    }
                    else
                    {
                        // the process was reset in between our checks, try to use the new service:
                        newService.Dispose(joinThreads: false);
                        currentRemoteService = previousService;
                    }
                }

                _errorOutput.WriteLine(FeaturesResources.Unable_to_create_hosting_process);
            }
            catch (OperationCanceledException)
            {
                // The user reset the process during initialization.
                // The reset operation will recreate the process.
            }
            catch (Exception e) when(FatalError.Report(e))
            {
                throw ExceptionUtilities.Unreachable;
            }

            return(default(InitializedRemoteService));
        }
Ejemplo n.º 6
0
        private void Dispose(bool joinThreads, bool disposing)
        {
            if (disposing)
            {
                GC.SuppressFinalize(this);
                DisposeChannel();
            }

            if (_lazyRemoteService != null)
            {
                _lazyRemoteService.Dispose(joinThreads);
                _lazyRemoteService = null;
            }
        }
Ejemplo n.º 7
0
        private async Task <IService> TryGetOrCreateRemoteServiceAsync()
        {
            ThrowIfDisposed();

            try
            {
                var currentRemoteService = _lazyRemoteService;

                for (var attempt = 0; attempt < MaxAttemptsToCreateProcess; attempt++)
                {
                    if (currentRemoteService == null)
                    {
                        return(null);
                    }

                    var initializedService = await currentRemoteService.InitializedService.Value.ConfigureAwait(false);

                    if (initializedService != null && initializedService.Process.IsAlive())
                    {
                        return(initializedService.Service);
                    }

                    // Service failed to start or initialize or the process died.
                    var newService = new LazyRemoteService(this);

                    var previousService = Interlocked.CompareExchange(ref _lazyRemoteService, newService,
                                                                      currentRemoteService);
                    if (previousService == currentRemoteService)
                    {
                        // we replaced the service whose process we know is dead:
                        currentRemoteService.Dispose();
                        currentRemoteService = newService;
                    }
                    else
                    {
                        // the process was reset in between our checks, try to use the new service:
                        newService.Dispose();
                        currentRemoteService = previousService;
                    }
                }
            }
            catch (OperationCanceledException)
            {
                // The user reset the process during initialization.
                // The reset operation will recreate the process.
            }
            return(null);
        }
Ejemplo n.º 8
0
        public async Task ResetAsync()
        {
            // replace the existing service with a new one:
            var newService = new LazyRemoteService(this);

            var oldService = Interlocked.Exchange(ref _lazyRemoteService, newService);
            oldService?.Dispose();

            await TryGetOrCreateRemoteServiceAsync().ConfigureAwait(false);
        }
Ejemplo n.º 9
0
        private async Task<Service> TryGetOrCreateRemoteServiceAsync()
        {
            try
            {
                var currentRemoteService = _lazyRemoteService;

                // disposed or not reset:
                Debug.Assert(currentRemoteService != null);

                for (var attempt = 0; attempt < MaxAttemptsToCreateProcess; attempt++)
                {
                    var initializedService = await currentRemoteService.InitializedService.Value.ConfigureAwait(false);
                    if (initializedService != null && initializedService.Process.IsAlive())
                    {
                        return initializedService.Service;
                    }

                    // Service failed to start or initialize or the process died.
                    var newService = new LazyRemoteService(this);

                    var previousService = Interlocked.CompareExchange(ref _lazyRemoteService, newService, currentRemoteService);
                    if (previousService == currentRemoteService)
                    {
                        // we replaced the service whose process we know is dead:
                        currentRemoteService.Dispose();
                        currentRemoteService = newService;
                    }
                    else
                    {
                        // the process was reset in between our checks, try to use the new service:
                        newService.Dispose();
                        currentRemoteService = previousService;
                    }
                }
            }
            catch (OperationCanceledException)
            {
                // The user reset the process during initialization. 
                // The reset operation will recreate the process.
            }
            return null;
        }
Ejemplo n.º 10
0
 public void Dispose()
 {
     _disposed = true;
     _lazyRemoteService?.Dispose();
     _lazyRemoteService = null;
 }