并行压缩C#

本文关键字:压缩 并行 | 更新日期: 2023-09-27 18:21:21

是否可以使用Parallel.Foreach或其他方法优化此代码?

using (var zipStream = new ZipOutputStream(OpenWriteArchive()))
{
    zipStream.CompressionLevel = CompressionLevel.Level9;    
    foreach (var document in docuemnts)
    {
        zipStream.PutNextEntry(GetZipEntryName(type));    
        using (var targetStream = new MemoryStream()) // document stream
        {
            DocumentHelper.SaveDocument(document.Value, targetStream, type);    
            targetStream.Position = 0; targetStream.CopyTo(zipStream);
        }    
        GC.Collect();
    };
}

问题是DotNetZip和SharpZipLib的ZipOutputStream不支持位置更改或查找。

从多个线程写入zip流会导致错误。也不可能将结果流累积到ConcurrentStack beacuse应用程序可以处理1000多个文档,应该可以将流压缩并保存到云中在飞行中。

有什么办法解决这个问题吗?

并行压缩C#

通过使用ProducerConsumerQueue(生产者-消费者模式)解决。

using (var queue = new ProducerConsumerQueue<byte[]>(HandlerDelegate))
{
    Parallel.ForEach(documents, document =>
    {
        using (var documentStream = new MemoryStream())
        {
            // saving document here ...
            queue.EnqueueTask(documentStream.ToArray());
        }
    });
}
protected void HandlerDelegate(byte[] content)
{
    ZipOutputStream.PutNextEntry(Guid.NewGuid() + ".pdf");
    using (var stream = new MemoryStream(content))
    {
        stream.Position = 0; stream.CopyTo(ZipOutputStream);
    }
}

尝试在平行foreach内减少zipstream,如:

Parallel.ForEach(docuemnts, (document) =>
            {
                using (var zipStream = new ZipOutputStream(OpenWriteArchive()))
                {
                    zipStream.CompressionLevel = CompressionLevel.Level9;
                    zipStream.PutNextEntry(GetZipEntryName(type));
                    using (var targetStream = new MemoryStream()) // document stream
                    {
                        DocumentHelper.SaveDocument(document.Value, targetStream, type);
                        targetStream.Position = 0; targetStream.CopyTo(zipStream);
                    }
                    GC.Collect();
                }
            });

再见!