【问题标题】:Notify the ActionBlock is completed to another class通知 ActionBlock 完成到另一个类
【发布时间】:2020-05-01 03:58:05
【问题描述】:

我编写了一个方法来实现 TPL ActionBlock,它将执行一个函数来查找我要发布到块的元素的 XPath。我正在从实时应用程序发送元素(每当用户找到一个元素时将其发布到块中)。现在,当我从另一个类调用保存按钮时,我想检查块是否完成。逻辑是如果ActionBlok在我们单击保存按钮时完成,元素将保存一些保存逻辑,否则显示一个消息框尚未准备好。这是第一次,这个想法是可行的,但从第二个元素开始,Actionblock 不接受任何东西。我使用block.Complete()block.Completion.Wait() 进行保存检查。现在我可以证明我正在调用代码/逻辑。

  1. 创建元素后,将其发布ActionBlock
    Class1
......
jobQ.Enqueue(familarizedElement);
......
  1. ActionBlock
    Class2
public class TPLCommonDataFlow
{
    private ActionBlock<Element> _jobs;
    public static bool TPLFlowStatus = false;
    public static string JobStatus = string.Empty;
    public TPLCommonDataFlow()
    {
        var executionDataflowBlockOptions = new ExecutionDataflowBlockOptions()
        {
            MaxDegreeOfParallelism = 2,
        };

        _jobs = new ActionBlock<Element>((job) =>
        {
            Thread.Sleep(5);
            File.WriteAllText("C:\\Temp\\A.txt", "Started" + _jobs.InputCount.ToString());
            JobStatus = "started";
            Familiarization.FindAndUpdateXPath(job);
            File.WriteAllText("C:\\Temp\\A.txt", "Finished");
        }, executionDataflowBlockOptions);
        _jobs.Complete();


        //Wait for all messages to propagate through the network
        _jobs.Completion.Wait();

        //Checking all jobs are completed or not, if completed changing the boo, value.
        if (_jobs.InputCount == 0)
        {
            TPLFlowStatus = true;
            JobStatus = "stoped";
        }
    }
}
  1. 为了保存,我正在检查 TPLFlowStatus 布尔值
    Class3
if (class2.TPLFlowStatus == true)
{
    //Save Logic
}
else
{
    //Message Box showing Not Ready
}

现在我想要的是在每次作业完成时检查保存逻辑中的每个元素是否完成。如果在Queue 中有两个元素且一个已完成的块,则在按下保存按钮后需要弹出MessageBox。如果在块中全部完成,则需要进入保存逻辑。

【问题讨论】:

  • 欢迎来到 Stack Overflow。请通过tour 了解 Stack Overflow 的工作原理,并阅读How to Ask 以了解如何提高问题的质量。然后edit你的问题包含你的源代码作为minimal reproducible example,它可以被其他人编译和测试。
  • 看来你从来没有Post_jobs 块做任何事情。除此之外,尚不清楚您要达到的目标。我注意到TPLFlowStatusJobStatus 属性是static,这没有多大意义。另外,我建议不要使用File.WriteAllText 登录,而是切换到proper logging framework

标签: c# task-parallel-library tpl-dataflow


【解决方案1】:

您看到的问题是,当一个块完成后,它将不再接受新消息,您已经告诉该块您已完成发送消息。要开始发送新的一批消息,您可以通过不调用 complete 并以另一种方式跟踪批处理完成来保持块处于活动状态,或者您可以只是重置块。像这样的简单工人可能就是您要寻找的:

public class DataflowWorker
{
    private ActionBlock<string> _jobs;

    private void BuildJobsHandler()
    {
        _jobs = new ActionBlock<string>(x => Console.WriteLine(x) /*Do your work in the action block*/);
    }

    public async Task Enque(string element)
    {
        await _jobs.SendAsync(element);
    }

    public async Task CompleteJobsAndSave()
    {
        _jobs.Complete();
        await _jobs.Completion;
        //Save data when complete
        BuildJobsHandler();
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-09-06
    • 1970-01-01
    • 1970-01-01
    • 2012-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-08
    相关资源
    最近更新 更多