有条件地阻止IEnumerable<;t>;产生返回结果
本文关键字:gt 结果 返回 lt IEnumerable 有条件 | 更新日期: 2023-09-27 18:30:01
我希望有人能帮我找到一个更有效的解决下面问题的方法。我在多线程管道中使用IEnumerableyield返回模式。然而,在大多数情况下,这都很好,在某些情况下,我需要管道中的操作同步进行,而不是在并行线程中进行,以获得正确的结果。(即遇到并发问题)。
现有代码为:
public override IEnumerable<Row> Execute(IEnumerable<Row> rows)
{
foreach (Row row in rows)
{
//do some work....
yield return row;
}
}
我正在考虑创建一个可选参数来控制枚举器的阻塞输出与非阻塞输出;类似的东西
public override IEnumerable<Row> Execute(IEnumerable<Row> rows, bool BlockingExecution)
{
if (BlockingExecution)
{
return BlockingExecute(rows);
}
else
{
return NonBlockingExecute(rows);
}
}
private IEnumerable<Row> NonBlockingExecute(IEnumerable<Row> rows)
{
foreach (Row row in rows)
{
//do some work....
yield return row;
}
}
private IEnumerable<Row> BlockingExecute(IEnumerable<Row> rows)
{
List<Row> BlockingResult = new List<Row>();
foreach(Row r in NonBlockingExecute(rows))
{
BlockingResult.Add(r);
}
return BlockingResult;
}
在BlockingExecute函数中,将IEnumerable的副本创建到List中以强制刷新整个管道似乎效率低下。有更好的方法吗?
通常,"阻塞执行"会在一定程度上效率低下。但我可能会将ToArray
用于该表单,并且您的非阻塞版本有点令人困惑。它真的应该为每一个做工作吗?
我可能会这么做。
public override IEnumerable<Row> Execute(IEnumerable<Row> rows, bool BlockingExecution)
{
if (BlockingExecution)
{
return rows.ToArray();
}
else
{
return NonBlockingExecute(rows); // or just "return rows". It seems like the best
// practice here, in most cases anyway
// would be to move that work elsewhere
}
}
private IEnumerable<Row> NonBlockingExecute(IEnumerable<Row> rows)
{
foreach (Row row in rows)
{
//do some work....
yield return row;
}
}
但是,是的,阻塞版本仍然需要对同一列表进行多次迭代(一次用于创建数组,一次用于读取数组)。我不确定有什么方法可以逃避,因为你想用某种方式把它全部加载到内存中。