private async Task RunAsyncHelper() { try { await Task.WhenAny( shutdownCancellationTokenSource.Token.AsTask(), Task.WhenAll( Go(async() => { var remoteToLocalHandshake = (HandshakeDto)await payloadUtils.ReadPayloadAsync(ns, shutdownCancellationTokenSource.Token).ConfigureAwait(false); remoteIdentity = remoteToLocalHandshake.Identity; }), Go(async() => { var localToRemoteHandshake = new HandshakeDto { Identity = localIdentity }; await payloadUtils.WritePayloadAsync(ns, localToRemoteHandshake, writerLock, shutdownCancellationTokenSource.Token).ConfigureAwait(false); }))).ConfigureAwait(false); if (shutdownCancellationTokenSource.IsCancellationRequested) { return; } isHandshakeComplete = true; var readerTask = RunReaderAsync(shutdownCancellationTokenSource.Token).Forgettable(); var writerTask = RunWriterAsync(shutdownCancellationTokenSource.Token).Forgettable(); tcpRoutingContextContainer.AssociateRemoteIdentityOrThrow(remoteIdentity.Id, this); routingTable.Register(remoteIdentity.Id, this); peerTable.GetOrAdd(remoteIdentity.Id).HandleInboundPeerIdentityUpdate(remoteIdentity); configuration.HandleRemoteHandshakeCompletion(remoteIdentity); try { await Task.WhenAny( readerTask, writerTask, shutdownCancellationTokenSource.Token.AsTask() ).ConfigureAwait(false); shutdownCancellationTokenSource.Cancel(); } catch (OperationCanceledException) when(isShutdown) { } } catch (Exception e) { Debug($"RunAsync threw {e}"); } finally { if (remoteIdentity != null) { routingTable.Unregister(remoteIdentity.Id, this); tcpRoutingContextContainer.RemoveOrThrow(this); tcpRoutingContextContainer.UnassociateRemoteIdentityOrThrow(remoteIdentity.Id, this); } } }