gpt4 book ai didi

c# - Parallel.Foreach + yield 返回?

转载 作者:IT王子 更新时间:2023-10-29 04:27:51 25 4
gpt4 key购买 nike

我想像这样使用并行循环处理一些东西:

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

}

好的,它工作正常。但是,如果我希望 FillLogs 方法返回一个 IEnumerable 怎么办?

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

}

编辑

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

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

但是我把 cpt.Logs = cpt.GetRawLogs().ToList(); 指令放在哪里

最佳答案

简短版本——不,这是不可能通过迭代器 block 实现的;较长的版本可能涉及调用者的迭代器线程(执行出队)和并行工作程序(执行入队)之间的同步队列/出队;但作为旁注 - 日志通常是 IO 绑定(bind)的,并行化 IO 绑定(bind)的东西通常效果不佳。

如果调用者要花一些时间来消费每一个,那么一次只处理一个日志的方法可能有一些优点,但可以while 调用方正在消费之前的日志;即它在 yield 之前开始一个Task 下一个项目,并在 之后等待完成yield... 但这又很复杂。作为一个简化的例子:

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();
}

关于c# - Parallel.Foreach + yield 返回?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8412879/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com