/**
         * Construct client for accessing Peer eventing service using the existing managedChannel.
         */
        public PeerEventServiceClient(Peer peer, Endpoint endpoint, Properties properties, PeerOptions peerOptions)
        {
            channelBuilder             = endpoint;
            filterBlock                = peerOptions.IsRegisterEventsForFilteredBlocks;
            this.peer                  = peer;
            name                       = peer.Name;
            url                        = peer.Url;
            channelName                = peer.Channel.Name;
            toString                   = $"PeerEventServiceClient{{id: {Config.Instance.GetNextID()}, channel: {channelName}, peerName: {name}, url: {url}}}";
            this.peerOptions           = peerOptions;
            clientTLSCertificateDigest = endpoint.GetClientTLSCertificateDigest();

            channelEventQue = peer.Channel.ChannelEventQueue;

            if (null == properties)
            {
                peerEventRegistrationWaitTimeMilliSecs = PEER_EVENT_REGISTRATION_WAIT_TIME;
            }
            else
            {
                peerEventRegistrationWaitTimeMilliSecs = properties.GetLongProperty("peerEventRegistrationWaitTime", PEER_EVENT_REGISTRATION_WAIT_TIME);
            }
        }
        public void Shutdown(bool force)
        {
            if (shutdown)
            {
                return;
            }
            string me = ToString();

            logger.Debug($"{me} is shutting down.");
            try
            {
                dtask.Cancel();
            }
            catch (Exception e)
            {
                logger.Error(ToString() + " error message: " + e.Message, e);
            }

            shutdown = true;
            Channel lchannel = managedChannel;

            managedChannel = null;

            if (lchannel != null)
            {
                if (force)
                {
                    try
                    {
                        lchannel.ShutdownAsync().GetAwaiter().GetResult();
                    }
                    catch (Exception e)
                    {
                        logger.WarnException(e.Message, e);
                    }
                }
                else
                {
                    bool isTerminated = false;
                    try
                    {
                        isTerminated = lchannel.ShutdownAsync().Wait(3 * 1000);
                    }
                    catch (Exception e)
                    {
                        logger.DebugException(e.Message, e); //best effort
                    }

                    if (!isTerminated)
                    {
                        try
                        {
                            lchannel.ShutdownAsync().GetAwaiter().GetResult();
                        }
                        catch (Exception e)
                        {
                            logger.Debug(me + " error message: " + e.Message, e); //best effort
                        }
                    }
                }
            }

            channelEventQue = null;
            logger.Debug($"{me} is down.");
        }