我有一个控制台应用程序,应该批量调用并压缩大文件,我想使用DataFlow,一切正常,除了完成
请考虑以下代码
public static void CompressFiles(string folder)
{
var bufferBlock = new BufferBlock<FileInfo>();
bufferBlock.LinkTo(Target(), new DataflowLinkOptions() { PropagateCompletion = true});
var files = GetFilesFromFolder(folder);
Parallel.ForEach(files, file =>
{
bufferBlock.Post(file);
});
Stopwatch sw = new Stopwatch();
sw.Start();
Parallel.ForEach(files, file =>
{
CreateFileT(file.FullName);
});
sw.Stop();
// Task.WaitAll(bufferBlock.Completion);
bufferBlock.Completion.Wait();
string tempoImpiegato =
$"[Generatore PDZ] : tempo impiegato per la generazione di {files.Length} pdz : {sw.Elapsed}";
LogManager.GetLogger("normal").Info(tempoImpiegato);
}
和压缩ActionBlock
private static ActionBlock<FileInfo> Target()
{
return new ActionBlock<FileInfo>(file =>
{
FileInfo bolFileName = new FileInfo(file.FullName.Replace($"{ApplicationHelper.FileExtensionPdf}", $"{ApplicationHelper.FileExtensionBOL}"));
FileInfo zipFileName = new FileInfo(file.FullName.Replace($"{ApplicationHelper.FileExtensionPdf}", $"{ApplicationHelper.FileExtensionPdz}"));
if (!File.Exists(file.FullName) || !File.Exists(bolFileName.FullName))
{
string s = $"File {file.FullName} o {bolFileName.FullName} non esistenti o inaccessibili";
Log.Warning(s);
}
else
{
try
{
using (ZipOutputStream s = new ZipOutputStream(zipFileName.OpenWrite()))
{
s.SetLevel(9);
ZipEntry entry1 = new ZipEntry(file.Name);
ZipEntry entry2 = new ZipEntry(bolFileName.Name);
entry1.Size = file.Length;
entry2.Size = bolFileName.Length;
byte[] buffer = ReadBytesFromFileInfo(file);
byte[] bufferBol = ReadBytesFromFileInfo(bolFileName);
s.PutNextEntry(entry1);
s.Write(buffer,0,buffer.Length);
s.PutNextEntry(entry2);
s.Write(bufferBol, 0, bufferBol.Length);
}
}
catch (Exception ex)
{
Log.Error(ex, "");
}
}
});
}
使用bufferBlock.Completion.Wait()
阻止程序而不进一步......我做错了什么,因为我已将PropagateCompletion
设为true且Target()
有效(它会生成文件) )
答案 0 :(得分:3)
您正在等待完成,但您没有表示完成。 BufferBlock
正在等待更多项目,它不知道您不会再发布任何项目。
要发出完成信号,您需要在等待完成前致电Complete
:
block.Complete();
await block.Completion;