【问题标题】:C# Is a Parallel foreach while loop possible?C# 是否可以使用并行 foreach while 循环?
【发布时间】:2010-08-15 13:37:36
【问题描述】:

我不确定 Parallel.foreach 的内部线程处理是如何工作的,以及它是否可以保证这样的构造可以工作?

Parallel.Foreach(Connections, c =>
    {
        Input in = c.getInput();
        while (in.hasNext()) {
            object o = in.getNext();
            dosomething(o);
        }
    }
);

其中 in.hasNext() 只是等待输入流中的一个对象并返回 true。基本上我可以在一个并行的 foreach 结构中运行一堆无限的 while 循环,同时保证它们都将同时运行。

(对于勇敢的人,我可以调整这个,以便我可以通过添加(和删除,这应该是微不足道的)连接来编辑连接列表,它仍然会从列表中的所有连接中读取输入)。

【问题讨论】:

  • 这应该可行,当你尝试它时会发生什么?
  • 我可以尝试,但我不能保证它永远不会产生竞争条件。给我 15 分钟的时间来设置一个测试服务器/客户端。
  • 我认为设置快速测试服务器/客户端会像在 Java 中一样简单快捷。 C# 没那么好。
  • 如果您要修改 Connections 集合,您可能不想使用 Parallel.Foreach,而应该自己创建并跟踪 Task 实例。当您需要对一组(静态)项目进行并行处理时,Parallel.Foreach 助手更适合。
  • @Raynos:确实,您需要从阻塞 I/O 切换到事件驱动。 I/O 调用的 .NET Begin/End 模型在下面使用 I/O 完成端口,这比每个连接一个线程要好得多。

标签: c# multithreading input parallel-processing


【解决方案1】:
  1. 使用它的线程数是有限的,所以会一个接一个地处理一些元素。

  2. 枚举时编辑列表不好。您可能会遇到异常(取决于您使用的列表

  3. 为什么不为每个连接启动一个新线程?

示例代码:

public ConnectionOpen(data)  
{  
    Connection conn=new ...  
    lock(Connections)  
    {  
         Connections.Add(conn);  
    }  

    new Thread(()=>  
    {  
        Receive(conn);//infinite loop goes here  
    }).Start();  
}  

public ConnectionClose(conn)  
{  
    bool removed=false;  
    lock(Connections)  
    {  
        removed=Connections.Remove(conn);  
    }  
    if(removed) conn.StopReceiving();  
}  

【讨论】:

  • 我试图更好地格式化该代码,但由于某种原因,StackO 解析器遇到了问题。
  • 有时除了优化代码(例如网站)之外还需要开发速度,而您给我的这部分证明非常宝贵
【解决方案2】:

基本上我可以在一个并行的foreach结构中运行一堆无限while循环,同时保证它们都将同时运行

没有。只有有限数量的工作线程会同时启动,所以如果你运行的无限循环比线程数多,最后一个永远不会运行......

【讨论】:

    【解决方案3】:

    从技术上讲,这段代码可以工作,但“同时”运行的线程的精确数量会有所不同。

    除了并行扩展之外,.NET 4 还在线程池中添加了“爬山”和线程注入,所以基本上 .NET 线程池会尝试将线程添加到 Parallel.ForEach 循环中,以查看是否有更多线程完成,因为你永远不会完成线程数会有所不同,但我猜这并不理想。

    您可以尝试使用 ParallelWhile 构造,该团队已经在博客中介绍了几种方法来做到这一点,here is one

    【讨论】:

    • 并行while循环并行运行while的do块。我试图在 do 块中获得一个带有无限循环的并行 for 循环,以便 for 循环的每个部分都运行,即使它是一个无限循环
    • 我认为您不会使用 Parallel.ForEach 获得这种行为,听起来您希望在 N 很大的情况下同时运行 N 个线程。为什么你需要同时运行这么多线程?
    猜你喜欢
    • 2023-04-09
    • 1970-01-01
    • 2015-09-08
    • 2018-02-18
    • 1970-01-01
    • 1970-01-01
    • 2020-09-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多