C# 可以并行 foreach while 循环吗?

发布于 2024-09-15 02:40:25 字数 454 浏览 3 评论 0 原文

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

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

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

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

I'm not sure how the internal thread handling of Parallel.foreach works and whether it can guarantee that a construct like this would work?

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

where in.hasNext() just waits for an object in the input stream and returns true. Basically can I run a bunch of infinite while loops in a parallel foreach structure whilst guaranteeing that they will all run at the same time.

(For the brave, can I adjust this so I can edit the connection list by adding (and removing, which should be trivial) connections and it will still read input from all connections in the list).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

萌逼全场 2024-09-22 02:40:25
  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();  
}  
  1. The number of threads using it is limited, so some elements will be processed one after another.

  2. Editing lists while enumerating is not good. You will likely get an exception (depends on the list you're using

  3. Why not start a new thread per connection?

Example code:

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();  
}  
悲凉≈ 2024-09-22 02:40:25

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

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

Basically can I run a bunch of infinite while loops in a parallel foreach structure whilst guaranteeing that they will all run at the same time

No. Only a limited number of worker threads will be started concurrently, so if you run more infinite loops than there are threads, the last ones will never run...

辞旧 2024-09-22 02:40:25

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

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

您可以尝试使用 ParallelWhile 构造,该团队已在博客中介绍了几种执行此操作的方法,这是一个

Technically, this code will work, but the precise number of threads running "simulataneously" will vary.

In addition to the parallel extensions, .NET 4 also added 'hill climbing'and thread injection to the thread pool, so basically the .NET threadpool will try adding threads to the Parallel.ForEach loop to see if more threads get completed, since yours will never complete the number of threads will vary, but I'm guessing will be non-ideal.

You might try using a ParallelWhile construct, the team has blogged about a couple ways to do this, here is one.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文