| File: DiagnosticsClient\DiagnosticsClientConnector.cs | Web Access |
| Project: src\diagnostics\src\Microsoft.Diagnostics.NETCore.Client\Microsoft.Diagnostics.NETCore.Client.csproj (Microsoft.Diagnostics.NETCore.Client) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; namespace Microsoft.Diagnostics.NETCore.Client { /// <summary> /// A connector that allows to create a <see cref="DiagnosticsClient"/> from a diagnostic port. /// </summary> public sealed class DiagnosticsClientConnector : IAsyncDisposable { private bool _disposed; private readonly IAsyncDisposable _server; internal DiagnosticsClientConnector(DiagnosticsClient diagnosticClient, IAsyncDisposable server) { _server = server; Instance = diagnosticClient; } /// <summary> /// Gets the <see cref="DiagnosticsClient"/> instance. /// </summary> public DiagnosticsClient Instance { get; } /// <inheritdoc /> public async ValueTask DisposeAsync() { if (_disposed) { return; } if (_server != null) { await _server.DisposeAsync().ConfigureAwait(false); } _disposed = true; } /// <summary> /// Create a new <see cref="DiagnosticsClientConnector"/> instance using the specified diagnostic port. /// </summary> /// <param name="diagnosticPort">The diagnostic port.</param> /// <param name="ct">The token to monitor for cancellation requests.</param> /// <returns>A <see cref="DiagnosticsClientConnector"/> instance</returns> public static async Task<DiagnosticsClientConnector> FromDiagnosticPort(string diagnosticPort, CancellationToken ct) { if (diagnosticPort is null) { throw new ArgumentNullException(nameof(diagnosticPort)); } IpcEndpointConfig portConfig = IpcEndpointConfig.Parse(diagnosticPort); if (portConfig.IsListenConfig) { string fullPort = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? portConfig.Address : Path.GetFullPath(portConfig.Address); ReversedDiagnosticsServer server = new(fullPort); server.Start(); try { IpcEndpointInfo endpointInfo = await server.AcceptAsync(ct).ConfigureAwait(false); return new DiagnosticsClientConnector(new DiagnosticsClient(endpointInfo.Endpoint), server); } catch (TaskCanceledException) { //clean up the server await server.DisposeAsync().ConfigureAwait(false); if (!ct.IsCancellationRequested) { throw; } return null; } } Debug.Assert(portConfig.IsConnectConfig); return new DiagnosticsClientConnector(new DiagnosticsClient(portConfig), null); } } }