public Task <string> PublishAsync(string subject, byte[] data)
        {
            PublishAck    a = publish(subject, data, null);
            Task <string> t = new Task <string>(() =>
            {
                a.wait();
                return(a.GUID);
            });

            t.Start();
            return(t);
        }
        internal PublishAck publish(string subject, byte[] data, EventHandler <StanAckHandlerArgs> handler)
        {
            string localAckSubject = null;
            long   localAckTimeout = 0;

            string subj      = this.pubPrefix + "." + subject;
            string guidValue = newGUID();

            byte[] b = ProtocolSerializer.createPubMsg(clientID, guidValue, subject, data);

            PublishAck a = new PublishAck(this, guidValue, handler, opts.PubAckWait);

            lock (mu)
            {
                if (nc == null)
                {
                    throw new StanConnectionClosedException();
                }

                while (!pubAckMap.TryAdd(guidValue, a))
                {
                    var bd = pubAckMap;

                    Monitor.Exit(mu);
                    // Wait for space outside of the lock so
                    // acks can be removed.
                    bd.waitForSpace();
                    Monitor.Enter(mu);

                    if (nc == null)
                    {
                        throw new StanConnectionClosedException();
                    }
                }

                localAckSubject = ackSubject;
                localAckTimeout = opts.ackTimeout;
            }

            try
            {
                nc.Publish(subj, localAckSubject, b);
            }
            catch
            {
                removeAck(guidValue);
                throw;
            }

            return(a);
        }
        private void processAck(object sender, MsgHandlerEventArgs args)
        {
            PubAck pa = new PubAck();

            try
            {
                ProtocolSerializer.unmarshal(args.Message.Data, pa);
            }
            catch (Exception)
            {
                // TODO:  (cls) handle this...
                return;
            }

            PublishAck a = removeAck(pa.Guid);

            if (a != null)
            {
                a.invokeHandler(pa.Guid, pa.Error);
            }
        }