【问题标题】:TPL Dataflow and console application doesn't terminate the applicationTPL 数据流和控制台应用程序不会终止应用程序
【发布时间】:2015-12-11 10:50:42
【问题描述】:

我有一个控制台应用程序,应该批量调用并压缩大文件,我想使用 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,你可以直接发帖到ActionBlock。 - 发布到并行内的块可能没有用。 - 您可能应该使用 async-await 而不是阻塞(即await bufferBlock.Completion)同步等待块的完成

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


【解决方案1】:

您正在等待完成,但您没有发出完成信号。 BufferBlock 正在等待更多项目,它不知道您不会再向其中发布任何项目。

要发出完成信号,您需要在等待完成之前调用Complete

block.Complete();
await block.Completion;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-31
    • 1970-01-01
    相关资源
    最近更新 更多