public override async Task <BatchDeleteProcessor> RemovePrefixAsync(string bucketName, string prefix, int chunkSize, CancellationToken cancellationToken = default)
        {
            ValidateInstance();

            var processor = new BatchDeleteProcessor(async(IEnumerable <string> keys) =>
            {
                var finishedDelete   = false;
                var observableDelete = await _minioClient.RemoveObjectAsync(bucketName, keys, cancellationToken).ConfigureAwait(false);
                // Remove list of objects in objectNames from the bucket bucketName.
                observableDelete.Subscribe(
                    deleteError => Console.WriteLine("Object: {0}", deleteError.Key),
                    ex => Console.WriteLine("OnError: {0}", ex),
                    () => finishedDelete = true
                    );

                while (!finishedDelete)
                {
                    await Task.Delay(250);
                }
            });

            var bucketKeys     = new List <string>();
            var finishedList   = false;
            var prefixToFilter = (prefix.EndsWith("/") ? prefix : prefix + "/");
            var observable     = _minioClient.ListObjectsAsync(bucketName, prefixToFilter, true, cancellationToken);

            observable.Subscribe
            (
                item =>
            {
                bucketKeys.Add(item.Key);
                if (bucketKeys.Count >= chunkSize)
                {
                    processor.EnqueueChunk(bucketKeys);
                    bucketKeys = new List <string>();
                }
            },
                () =>
            {
                if (bucketKeys.Any())
                {
                    processor.EnqueueChunk(bucketKeys);
                }

                finishedList = true;
            }
            );

            while (!finishedList)
            {
                await Task.Delay(100);
            }

            return(processor);
        }
        public override async Task <BatchDeleteProcessor> RemovePrefixAsync(string bucketName, string prefix, int chunkSize, CancellationToken cancellationToken = default)
        {
            ValidateInstance();

            var processor = new BatchDeleteProcessor(async(IEnumerable <string> keys) =>
            {
                var deleteRequest = new DeleteObjectsRequest
                {
                    BucketName = bucketName,
                    Objects    = keys.Select(k => new KeyVersion {
                        Key = k
                    }).ToList()
                };
                await _client.DeleteObjectsAsync(deleteRequest, cancellationToken).ConfigureAwait(false);
            });

            ListObjectsV2Response response;
            var prefixToFilter           = (prefix.EndsWith("/") ? prefix : prefix + "/");
            ListObjectsV2Request request = new ListObjectsV2Request
            {
                BucketName = bucketName,
                Prefix     = prefixToFilter,
                MaxKeys    = chunkSize
            };

            do
            {
                response = await _client.ListObjectsV2Async(request);

                if (!response.S3Objects.Any())
                {
                    continue;
                }

                processor.EnqueueChunk(response.S3Objects.Select(o => o.Key));
                request.ContinuationToken = response.NextContinuationToken;
            } while (response.IsTruncated);

            return(processor);
        }