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)); }
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) { }