TPL数据流和控制台应用程序不会终止应用程序

时间:2015-12-11 10:50:43

标签: c# .net multithreading task-parallel-library tpl-dataflow

我有一个控制台应用程序,应该批量调用并压缩大文件,我想使用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()有效(它会生成文件) )

1 个答案:

答案 0 :(得分:3)

您正在等待完成,但您没有表示完成。 BufferBlock正在等待更多项目,它不知道您不会再发布任何项目。

要发出完成信号,您需要在等待完成前致电Complete

block.Complete();
await block.Completion;