我的情况是,我有BufferBlock<Stream>
来自外部来源的Stream
,让我们说文件系统或某个FTP服务器。这些文件Stream
将传递到另一个块并进行处理。
唯一的问题是其中一些文件是压缩的,我想在中间添加一个Block
,它会在必要时解压缩文件,并创建多个输出Stream
&#39; s为每个条目。
但我不想使用TransformBlockMany
,因为这意味着我必须完全接收ZIP Stream
并立即创建输出Stream
数组。
我希望只要条目准备好,此Block
就会收到ZIP Stream
,开始解压缩,Push
到下一个流,因此Process Block可以尽快开始处理因为第一个文件已解压缩,而不是等到所有内容都解压缩。
我该怎么做呢?
答案 0 :(得分:1)
我了解到我的问题无法一起使用yield
/ async
。但在重构之后,我摆脱了这种需求,并提出了以下(简化)版本:
var block = new TransformManyBlock<Stream, Stream>((input) => {
var archive = new System.IO.Compression.ZipArchive(input, System.IO.Compression.ZipArchiveMode.Read, true);
foreach (ZipArchiveEntry entry in archive.Entries)
{
if (string.IsNullOrWhiteSpace(entry.Name)) //is a folder
continue;
yield return entry.Open();
}
});
答案 1 :(得分:0)
您可以使用predicate linking块为您的解压缩逻辑设置中间块,以便您可以检查流是否存档,如下所示:
var buffer = new BufferBlock<Stream>();
var unzipper = new TransformManyBlock<Stream, Stream>(input => { /* unzip here */ });
var processBlock = new ActionBlock<Stream>(input => { /* process streams here */ });
buffer.LinkTo(unzipper, input => /* check is stream a zip archive */);
unzipper.LinkTo(processBlock);
buffer.LinkTo(processBlock);