public virtual Task InvokeAsync <TMessage>(
            ConsumerDescriptor descriptor,
            IConsumer consumer,
            ConsumeContext <TMessage> envelope,
            CancellationToken cancelToken = default) where TMessage : class
        {
            var d           = descriptor;
            var p           = descriptor.WithEnvelope ? (object)envelope : envelope.Message;
            var fastInvoker = FastInvoker.GetInvoker(d.Method);
            var ct          = cancelToken;

            Task task;

            if (d.IsAsync && !d.FireForget)
            {
                // The all async case.
                ct   = _asyncRunner.CreateCompositeCancellationToken(cancelToken);
                task = ((Task)InvokeCore(null, ct));
                task.ContinueWith(t =>
                {
                    if (t.IsFaulted)
                    {
                        HandleException(t.Exception, d);
                    }
                }, TaskContinuationOptions.None);
            }
            else if (d.FireForget)
            {
                // Sync or Async without await. Needs new dependency scope.
                task = d.IsAsync
                    ? _asyncRunner.RunTask((scope, ct) => ((Task)InvokeCore(scope, ct)))
                    : _asyncRunner.Run((scope, ct) => InvokeCore(scope, ct));
                task.ConfigureAwait(false);
            }
            else
            {
                // The all sync case
                try
                {
                    InvokeCore(null, ct);
                }
                catch (Exception ex)
                {
                    HandleException(ex, d);
                }

                task = Task.CompletedTask;
            }

            return(task);

            object InvokeCore(IComponentContext c = null, CancellationToken cancelToken = default)