public TChannel BuildChannel(TimeSpan timeout)
        {
            TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);

            this.InitializeAndFindAsync();

            TChannel innerChannel = null;
            bool     completed    = false;

            EndpointDiscoveryMetadata currentEndpointDiscoveryMetadata = null;

            try
            {
                do
                {
                    try
                    {
                        currentEndpointDiscoveryMetadata = this.discoveredEndpoints.Dequeue(timeoutHelper.RemainingTime());
                    }
                    catch (TimeoutException te)
                    {
                        throw FxTrace.Exception.AsError(new TimeoutException(SR.DiscoveryClientChannelOpenTimeout(timeoutHelper.OriginalTimeout), te));
                    }

                    if (currentEndpointDiscoveryMetadata == null)
                    {
                        if (this.totalDiscoveredEndpoints < 1)
                        {
                            throw FxTrace.Exception.AsError(new EndpointNotFoundException(SR.DiscoveryClientChannelEndpointNotFound, this.exception));
                        }
                        else
                        {
                            throw FxTrace.Exception.AsError(new EndpointNotFoundException(SR.DiscoveryClientChannelCreationFailed(this.totalDiscoveredEndpoints), this.exception));
                        }
                    }

                    if (timeoutHelper.RemainingTime() == TimeSpan.Zero)
                    {
                        throw FxTrace.Exception.AsError(new TimeoutException(SR.DiscoveryClientChannelOpenTimeout(timeoutHelper.OriginalTimeout)));
                    }

                    if (currentEndpointDiscoveryMetadata.ListenUris.Count == 0)
                    {
                        completed = this.CreateChannel(
                            ref innerChannel,
                            currentEndpointDiscoveryMetadata.Address,
                            currentEndpointDiscoveryMetadata.Address.Uri,
                            timeoutHelper);
                    }
                    else
                    {
                        foreach (Uri listenUri in currentEndpointDiscoveryMetadata.ListenUris)
                        {
                            completed = this.CreateChannel(
                                ref innerChannel,
                                currentEndpointDiscoveryMetadata.Address,
                                listenUri,
                                timeoutHelper);

                            if (completed)
                            {
                                break;
                            }
                        }
                    }
                }while (!completed);
            }
            finally
            {
                if (completed && TD.InnerChannelOpenSucceededIsEnabled())
                {
                    TD.InnerChannelOpenSucceeded(
                        currentEndpointDiscoveryMetadata.Address.ToString(),
                        GetVia(innerChannel).ToString());
                }

                this.Cleanup(timeoutHelper.RemainingTime());
            }

            return(innerChannel);
        }