public async Task <IAsyncDisposable> SubscribeAsync(
            IObserver <IStompMessage> observer,
            string destination,
            string ack      = null,
            bool useReceipt = true,
            IEnumerable <KeyValuePair <string, string> > extraHeaders = null,
            CancellationToken?cancellationToken = null)
        {
            string      subscriptionId         = Client.GetNextSubscriptionId();
            IDisposable disposableSubscription =
                new StompSubscription(
                    Client,
                    observer,
                    subscriptionId,
                    ack == StompAckValues.AckClientIndividualValue || ack == StompAckValues.AckClientValue,
                    TransactionId);

            try
            {
                await Client.WriteSubscribeAsync(
                    destination,
                    subscriptionId,
                    useReceipt?Client.GetNextReceiptId() : null,
                        ack,
                        extraHeaders,
                        cancellationToken);
            }
            catch (Exception)
            {
                disposableSubscription.Dispose();
                throw;
            }

            return(new AsyncActionDisposable(
                       async(cancelToken) =>
            {
                await Client.WriteUnsubscribeAsync(subscriptionId, useReceipt ? Client.GetNextReceiptId() : null, null, cancelToken);
                disposableSubscription.Dispose();
            }));
        }