简体   繁体   English

C#是一个并行foreach而while循环可能吗?

[英]C# Is a Parallel foreach while loop possible?

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的内部线程处理是如何工作的,以及它是否可以保证这样的构造能够工作?

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. in.hasNext()只是等待输入流中的对象并返回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. 基本上我可以在并行foreach结构中运行一堆无限while循环,同时保证它们将同时运行。

(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). (对于勇敢者,我可以调整这个,这样我就可以通过添加(并删除,这应该是微不足道的)连接来编辑连接列表,它仍然会读取列表中所有连接的输入。

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 基本上我可以在并行foreach结构中运行一堆无限while循环,同时保证它们将同时运行

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... 不会。只有有限数量的工作线程会同时启动,所以如果你运行的无限循环比线程更多,那么最后一个将永远不会运行...

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

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

You might try using a ParallelWhile construct, the team has blogged about a couple ways to do this, here is one . 您可以尝试使用ParallelWhile构造,该团队已经在博客中介绍了几种方法, 这里有一个

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM