Parallel.Foreach +收益回报? [英] Parallel.Foreach + yield return?

查看:162
本文介绍了Parallel.Foreach +收益回报?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用并行循环这样的处理的内容:

I want to process something using parallel loop like this :

public void FillLogs(IEnumerable<IComputer> computers)
{
    Parallel.ForEach(computers, cpt=>
    {
        cpt.Logs = cpt.GetRawLogs().ToList();
    });

}



好吧,它工作正常。但如何做,如果我想FillLogs方法返回一个IEnumerable

Ok, it works fine. But How to do if I want the FillLogs method return an IEnumerable ?

public IEnumerable<IComputer> FillLogs(IEnumerable<IComputer> computers)
{
    Parallel.ForEach(computers, cpt=>
    {
        cpt.Logs = cpt.GetRawLogs().ToList();
        yield return cpt // KO, don't work
    });

}

修改

这似乎不是可能的...但我用这样的:

It seems not to be possible... but I use something like this :

public IEnumerable<IComputer> FillLogs(IEnumerable<IComputer> computers)
{
    return computers.AsParallel().Select(cpt => cpt);
}

在这里我把 cpt.Logs = CPT

不过, .GetRawLogs()了ToList(); 指令

推荐答案

短版 - 不,这不是个通过迭代器阻断T可能;较长的版本可能涉及同步队列/调用者的迭代器线程之间和平行工人(做排队)出队(做出队);但作为一个侧面说明 - 日志通常IO绑定,并parallelising东西都是IO的限制往往不能很好地工作。

Short version - no, that isn't possible via an iterator block; the longer version probably involves synchronized queue/dequeue between the caller's iterator thread (doing the dequeue) and the parallel workers (doing the enqueue); but as a side note - logs are usually IO-bound, and parallelising things that are IO-bound often doesn't work very well.

如果主叫方是要。需要一些时间来的消耗的每一个,那么可能会有一些好处,以一种方法,一次只能处理一个记录,但能做到这一点的,而来电消耗以前登录;也就是说,它的开始 工作 作为下一个项目收益,并为产量完成后等待 ...但是,这是一次,相当复杂。作为一个简单的例子:

If the caller is going to take some time to consume each, then there may be some merit to an approach that only processes one log at a time, but can do that while the caller is consuming the previous log; i.e. it begins a Task for the next item before the yield, and waits for completion after the yield... but that is again, pretty complex. As a simplified example:

static void Main()
{
    foreach(string s in Get())
    {
        Console.WriteLine(s);
    }
}

static IEnumerable<string> Get() {
    var source = new[] {1, 2, 3, 4, 5};
    Task<string> outstandingItem = null;
    Func<object, string> transform = x => ProcessItem((int) x);
    foreach(var item in source)
    {
        var tmp = outstandingItem;

        // note: passed in as "state", not captured, so not a foreach/capture bug
        outstandingItem = new Task<string>(transform, item);
        outstandingItem.Start();

        if (tmp != null) yield return tmp.Result;
    }
    if (outstandingItem != null) yield return outstandingItem.Result;
}
static string ProcessItem(int i)
{
    return i.ToString();
}

这篇关于Parallel.Foreach +收益回报?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆