public async Task <IEnumerable <IEndpointInfo> > GetEndpointInfoAsync(CancellationToken token)
        {
            var endpointInfoTasks = new List <Task <EndpointInfo> >();

            // Run the EndpointInfo creation parallel. The call to FromProcessId sends
            // a GetProcessInfo command to the runtime instance to get additional information.
            foreach (int pid in DiagnosticsClient.GetPublishedProcesses())
            {
                endpointInfoTasks.Add(Task.Run(() =>
                {
                    try
                    {
                        return(EndpointInfo.FromProcessId(pid));
                    }
                    //Catch when the application is running a more privilaged socket than dotnet-monitor. For example, running a web app as administrator
                    //while running dotnet-monitor without elevation.
                    catch (UnauthorizedAccessException)
                    {
                        return(null);
                    }
                    //Most errors from IpcTransport, such as a stale socket.
                    catch (ServerNotAvailableException)
                    {
                        return(null);
                    }
                }, token));
            }

            await Task.WhenAll(endpointInfoTasks);

            return(endpointInfoTasks.Where(t => t.Result != null).Select(t => t.Result));
        }
Ejemplo n.º 2
0
        public async Task <IEnumerable <IEndpointInfo> > GetEndpointInfoAsync(CancellationToken token)
        {
            var endpointInfoTasks = new List <Task <EndpointInfo> >();

            // Run the EndpointInfo creation parallel. The call to FromProcessId sends
            // a GetProcessInfo command to the runtime instance to get additional information.
            foreach (int pid in DiagnosticsClient.GetPublishedProcesses())
            {
                endpointInfoTasks.Add(Task.Run(() => EndpointInfo.FromProcessId(pid)));
            }

            await Task.WhenAll(endpointInfoTasks);

            return(endpointInfoTasks.Select(t => t.Result));
        }
        private async Task ResumeAndQueueEndpointInfo(IpcEndpointInfo info, CancellationToken token)
        {
            try
            {
                // Send ResumeRuntime message for runtime instances that connect to the server. This will allow
                // those instances that are configured to pause on start to resume after the diagnostics
                // connection has been made. Instances that are not configured to pause on startup will ignore
                // the command and return success.
                var client = new DiagnosticsClient(info.Endpoint);
                try
                {
                    client.ResumeRuntime();
                }
                catch (ServerErrorException)
                {
                    // The runtime likely doesn't understand the ResumeRuntime command.
                }

                EndpointInfo endpointInfo = EndpointInfo.FromIpcEndpointInfo(info);

                await _endpointInfosSemaphore.WaitAsync(token).ConfigureAwait(false);

                try
                {
                    _endpointInfos.Add(endpointInfo);

                    OnAddedEndpointInfo(endpointInfo);
                }
                finally
                {
                    _endpointInfosSemaphore.Release();
                }
            }
            catch (Exception)
            {
                _server?.RemoveConnection(info.RuntimeInstanceCookie);

                throw;
            }
        }
        /// <summary>
        /// Returns true if the connection is not longer viable.
        /// </summary>
        private static async Task <bool> CheckNotViable(EndpointInfo info, CancellationToken token)
        {
            using var timeoutSource = new CancellationTokenSource();
            using var linkedSource  = CancellationTokenSource.CreateLinkedTokenSource(token, timeoutSource.Token);

            try
            {
                timeoutSource.CancelAfter(PruneWaitForConnectionTimeout);

                await info.Endpoint.WaitForConnectionAsync(linkedSource.Token).ConfigureAwait(false);
            }
            catch
            {
                // Only report not viable if check was not cancelled.
                if (!token.IsCancellationRequested)
                {
                    return(true);
                }
            }

            return(false);
        }
        private async Task PruneIfNotViable(EndpointInfo info, CancellationToken token)
        {
            using var timeoutSource = new CancellationTokenSource();
            using var linkedSource  = CancellationTokenSource.CreateLinkedTokenSource(token, timeoutSource.Token);

            try
            {
                timeoutSource.CancelAfter(PruneWaitForConnectionTimeout);

                await info.Endpoint.WaitForConnectionAsync(linkedSource.Token).ConfigureAwait(false);
            }
            catch
            {
                // Only remove the endpoint info if due to some exception
                // other than cancelling the pruning operation.
                if (!token.IsCancellationRequested)
                {
                    _endpointInfos.Remove(info);
                    OnRemovedEndpointInfo(info);
                    _server?.RemoveConnection(info.RuntimeInstanceCookie);
                }
            }
        }
 internal virtual void OnRemovedEndpointInfo(EndpointInfo info)
 {
 }
 internal virtual void OnAddedEndpointInfo(EndpointInfo info)
 {
 }