2016-12-01 9 views
6

私のシナリオでは、BufferBlock<Stream>が外部ソースからStreamを受け取っています。ファイルシステムまたはFTPサーバーとしましょう。これらのファイルStreamは、別のブロックに渡され、処理されます。TransformBlockの出力への出力

これらのファイルのいくつかは圧縮されており、必要に応じてファイルを解凍する中間にBlockを追加して、それぞれのエントリに対して複数の出力Streamを作成したいと思います。

しかし、私はTransformBlockManyを使用したくないと思います。これは、ZIP Streamを完全に受信し、すぐに出力Streamアレイを作成する必要があるためです。

私はこのBlockは、ZIP Streamを受ける解凍を開始したいと思う、および処理ブロックは、すぐに最初のファイルが解凍されるような処理を開始することができるようにPush次のストリームへのエントリーは、準備ができている時はいつでも、そしてないまで待ちますすべてが解凍されます。

どうすればいいですか?

+3

ZIP解凍にはどのライブラリを使用していますか? –

+2

System.IO.Compression.ZipFileを使用します。 – Gidon

+0

これまで私の問題は実際には非同期の部分であることを理解しています。非同期を使用しない場合は、TransformManyBlockでyield yieldを使用するだけです。しかし、私は非同期と共に利回りを使うことはできません。 – Gidon

答えて

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(); 

} 

}); 
0

セットアップpredicate linkingブロックを使用して解凍ロジックの中間ブロックは、あなたがチェックすることができますすることができますので、アーカイブをストリーミングするかどうか、このようなものです:一緒にyieldasync使用方法については

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); 

、あなたはGitHubと​​で利用可能AsyncEnumerableパッケージに試してみることがあります。