并行压缩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多个文档,应该可以将流压缩并保存到云中在飞行中。
有什么办法解决这个问题吗?
通过使用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();
}
});
再见!