TPL 数据流和控制台应用程序不会终止应用程序
TPL Dataflow and console application doesn't terminate the application
我有一个控制台应用程序,应该批量调用并压缩大文件,我想使用 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()
工作(它生成文件)
您正在等待完成,但您并未发出完成信号。 BufferBlock
正在等待更多项目,它不知道您不会 post 向其中添加更多项目。
要发出完成信号,您需要在等待完成之前调用 Complete
:
block.Complete();
await block.Completion;
我有一个控制台应用程序,应该批量调用并压缩大文件,我想使用 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);
}
和
的压缩ActionBlockprivate 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()
工作(它生成文件)
您正在等待完成,但您并未发出完成信号。 BufferBlock
正在等待更多项目,它不知道您不会 post 向其中添加更多项目。
要发出完成信号,您需要在等待完成之前调用 Complete
:
block.Complete();
await block.Completion;