public IEnumerable <IStreamPartition> Generate(Stream stream)
        {
            while (true)
            {
                byte[] buffer = new byte[PartitionSize];
                var    count  = stream.Read(buffer, 0, buffer.Length);
                if (count <= 0)
                {
                    break;
                }

                if (count < buffer.Length)
                {
                    Array.Resize(ref buffer, count);
                }

                var path = TempProcessFiles.NewProcessFilePath();
                File.WriteAllBytes(path, buffer);
                var partition = new FilePartition(path, buffer.LongLength);

                yield return(partition);
            }
        }
        public IAsyncEnumerable <IStreamPartition> GenerateAsync(Stream stream, CancellationToken cancellationToken)
        {
            var helper = new AsyncEnumerableHelper <IStreamPartition>();
            var arr    = new byte[PartitionSize];

            Action <byte[], int, int, CancellationToken> copier = (buffer, offset, count, CancellationToken) =>
            {
                if (offset < 0)
                {
                    return;
                }
                if (count <= 0)
                {
                    return;
                }
                var end = offset + count;

                while (offset < end)
                {
                    //todo: convert this to a Func<.., Task> so we can do the async without blocking.
                    var take = Math.Min(PartitionSize, end - offset);
                    if (arr.Length < take)
                    {
                        Array.Resize(ref arr, take);
                    }
                    else if (arr.Length > take)
                    {
                        arr = new byte[take];
                    }
                    Buffer.BlockCopy(buffer, offset, arr, 0, take);

                    var path = TempProcessFiles.NewProcessFilePath();
                    File.WriteAllBytes(path, arr);
                    var partition = new FilePartition(path, arr.LongLength);

                    helper.SetNext(partition);

                    offset += take;
                }
            };

            var cache = new StreamWriter(
                (data, offset, count) => {
                Console.WriteLine($"Received partition of size {data.Length} with offset {offset} and count {count}");
                copier(data, offset, count, CancellationToken.None);
            },
                (data, offset, count, ct) => {
                Console.WriteLine($"Received ASYNC partition of size {data.Length} with offset {offset} and count {count}");
                copier(data, offset, count, ct);
                return(Task.CompletedTask);
            },
                totalSize => { Console.WriteLine("Received total length"); });

            var task = stream
                       .CopyToAsync(cache, PartitionSize, cancellationToken)
                       .ContinueWith(done =>
            {
                Console.WriteLine("Copy To is DONE");
                helper.MarkComplete();
            });

            return(helper.GetEnumerable());
        }