【问题标题】:Better use of .net dataflow更好地使用 .net 数据流
【发布时间】:2017-08-19 04:54:30
【问题描述】:

我需要帮助以更好地安排 .NET TPL 数据流中的代码。这是代码

    var finalBlock = new ActionBlock<Category_KeywordsToMatch>(x =>
    {
        List<Resume> Resumes = new List<Resume>();

        using (var context = new IndepthRecruitDbContext())
        {
            Resumes = context.Resumes.Include("Candidate").ToList();
        }
        foreach (var res in Resumes)
        {
            var keywords = FindKeywords(x.KeywordsToMatch, res);
            if (keywords.Count > 0)
            {
                matchedCandidates_dataflow.Add(new MatchedCandidate
                {
                    Id = res.CandidateId,
                    Name = res.Candidate.Name,
                    Url = res.Url,
                    Uploaded = res.DateUploaded.ToShortDateString(),
                    MatchedKeywordsList = keywords
                });
            }
        }
    });

这是我链的最后一个区块。这里的动作块输入是 Category_KeywordsToMatch,它是一个包含工作类别和要在简历中匹配的关键字列表的类。 {类别,列出}。在块内部,我使用 foreach 循环来枚举简历列表。 有没有使用数据流更好的设计,比如简历可以作为不同的输入提供。 最终块是一个类别的最后一个块。我需要搜索多个类别的关键字。

【问题讨论】:

  • 如果你的Resumes没有改变,你可以做WriteOnceBlock,或者你可以试试BroadcastBlock,它接受委托复制值。
  • 感谢您的回复。我想知道我可以将这个最后一个块分成一些块链。我是 tpl 数据流的初学者,没有太多相同的教程。简历不变。我正在考虑将简历和 Category_KeywordsToMatch 的元组提供给其他块,然后在其他块中制作最终结果。 @VMAtm 能否请您给我您的 Skype 或任何其他 ID,以便我与您联系。

标签: .net tpl-dataflow


【解决方案1】:

假设matchedCandidates_dataflow 是一些线程安全的集合,您可以并行处理匹配简历,并在它们准备好后将它们添加到其中。 下面我附上了一种方法的示例代码。 例如,调用 BuildMatchingBlock(4) 将为您提供一个块,以确保您并行处理多达 4 个工作项。假设你在这里只做 CPU 工作,我建议确保并行度不大于你的核心数。我选择使用“SendAsync”界面,但您也可以使用“Post”,确保您了解它们之间的差异并选择最适合您的界面。您也可以将 BoundedCapacity 参数传递给 ExecutionDataflowBlockOptions

    private class WorkItem
    {
        public Category_KeywordsToMatch CategoryKeywordsToMatch { get; set; }
        public Resume Resume { get; set; }
        public WorkItem(Category_KeywordsToMatch c, Resume r)
        {
            CategoryKeywordsToMatch = c;
            Resume = r;
        }
    }

    private ActionBlock<Category_KeywordsToMatch> BuildMatchingBlock(int matchingParallelism)
    {
        var finalBlock = new ActionBlock<WorkItem>(
            workItem =>
            {
                var keywords = FindKeywords(workItem.CategoryKeywordsToMatch.KeywordsToMatch, workItem.Resume);
                if (keywords.Count > 0)
                {
                    // match...
                }
            },
            new ExecutionDataflowBlockOptions() { MaxDegreeOfParallelism = matchingParallelism });

        var preparatorBlock = new ActionBlock<Category_KeywordsToMatch>(
            async x =>
            {
                List<Resume> Resumes = new List<Resume>();
                // load resumes...

                foreach (var res in Resumes)
                {
                    await finalBlock.SendAsync(new WorkItem(x, res)).ConfigureAwait(false);
                }
            });

        return preparatorBlock;
    }

【讨论】:

    猜你喜欢
    • 2016-09-24
    • 2015-07-31
    • 2013-07-18
    • 1970-01-01
    • 2010-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多