public async Task StartAsync()

in src/Microsoft.Azure.SignalR.Common/ServiceConnections/ServiceConnectionBase.cs [152:218]


    public async Task StartAsync(string target = null)
    {
        if (Interlocked.CompareExchange(ref _started, 1, 0) != 0)
        {
            throw new InvalidOperationException("Connection already started!");
        }

        Status = ServiceConnectionStatus.Connecting;

        var connection = await EstablishConnectionAsync(target);
        if (connection != null)
        {
            _connectionContext = connection;
            Status = ServiceConnectionStatus.Connected;
            _serviceConnectionStartTcs.TrySetResult(true);
            try
            {
                TimerAwaitable syncTimer = null;
                try
                {
                    if (HubEndpoint != null && HubEndpoint.AccessKey is MicrosoftEntraAccessKey key)
                    {
                        syncTimer = new TimerAwaitable(TimeSpan.Zero, DefaultSyncAzureIdentityInterval);
                        _ = UpdateAzureIdentityAsync(key, syncTimer);
                    }
                    await ProcessIncomingAsync(connection);
                }
                finally
                {
                    // mark the status as Disconnected so that no one will write to this connection anymore
                    Status = ServiceConnectionStatus.Disconnected;
                    syncTimer?.Stop();

                    // when ProcessIncoming completes, clean up the connection

                    // TODO: Never cleanup connections unless Service asks us to do that
                    // Current implementation is based on assumption that Service will drop clients
                    // if server connection fails.
                    await CleanupClientConnections();
                }
            }
            catch (Exception ex)
            {
                Log.ConnectionDropped(Logger, _endpointName, ConnectionId, ex);
            }
            finally
            {
                // wait until all the connections are cleaned up to close the outgoing pipe
                // Don't allow write anymore when the connection is disconnected
                await _writeLock.WaitAsync();
                try
                {
                    // close the underlying connection
                    await DisposeConnection(connection);
                }
                finally
                {
                    _writeLock.Release();
                }
            }
        }
        else
        {
            Status = ServiceConnectionStatus.Disconnected;
            _serviceConnectionStartTcs.TrySetResult(false);
        }
    }