C# 并行压缩#
是否可以使用C# 并行压缩#,c#,parallel-processing,compression,C#,Parallel Processing,Compression,是否可以使用Parallel.Foreach或其他方法优化此代码 using (var zipStream = new ZipOutputStream(OpenWriteArchive())) { zipStream.CompressionLevel = CompressionLevel.Level9; foreach (var document in docuemnts) { zipStream.PutNextEntry(GetZipEntryN
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多个文档,并且应该能够将流压缩并保存到云中
在飞行中
有什么办法可以解决这个问题吗?尝试清除平行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();
}
});
再见 尝试清除平行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();
}
});
再见 通过使用
ProducerConsumerQueue
(生产者-消费者模式)解决
使用(var queue=new ProducerConsumerQueue(HandlerDelegate))
{
Parallel.ForEach(文档,文档=>
{
使用(var documentStream=new MemoryStream())
{
//正在此处保存文档。。。
queue.EnqueueTask(documentStream.ToArray());
}
});
}
受保护的无效HandlerDelegate(字节[]内容)
{
ZipOutputStream.putnextry(Guid.NewGuid()+“.pdf”);
使用(var流=新内存流(内容))
{
stream.Position=0;stream.CopyTo(ZipOutputStream);
}
}
使用ProducerConsumerQueue
(生产者-消费者模式)解决
使用(var queue=new ProducerConsumerQueue(HandlerDelegate))
{
Parallel.ForEach(文档,文档=>
{
使用(var documentStream=new MemoryStream())
{
//正在此处保存文档。。。
queue.EnqueueTask(documentStream.ToArray());
}
});
}
受保护的无效HandlerDelegate(字节[]内容)
{
ZipOutputStream.putnextry(Guid.NewGuid()+“.pdf”);
使用(var流=新内存流(内容))
{
stream.Position=0;stream.CopyTo(ZipOutputStream);
}
}
您必须将所有文件压缩到同一个归档文件中吗?是的,所有条目(文档)都应该压缩到同一个归档文件中如果ZipoutStream确实支持查找和位置更改,并且您成功实现了一个编组系统,允许多个线程同时写入,这仍然是你的瓶颈。这样的编组系统可能会导致比并行处理带来的开销更大的开销。是否必须将所有文件压缩到同一个存档中?是的,所有条目(文档)如果ZipOutputStream确实支持查找和位置更改,并且您成功实现了一个编组系统,允许多个线程同时写入,那么它仍然是您的瓶颈。这样的编组系统可能会导致比并行处理带来的开销更大的开销。所有文档都应该在同一个归档中所有文档都应该在同一个归档中