2010-03-02 104 views
5

我试图如下简化问题,C#线程问题

  1. 我身边有100多个文件,我想读,然后处理
  2. 对此我保持文件名的数组中的数据和位置
  3. 我生成线程来完成读取文件的工作。

现在我的问题是我想确保一次只有5个线程产生,因为开始100 +线程根本不是好主意。

所以请告诉我,我应该用什么方法来确保只有5个线程在工作,并且只要他们中的一个完成了,就可以启动新线程。

谢谢大家,

+0

为什么要求只有5个线程同时工作? – Andrew 2010-03-02 05:30:24

+0

我想稍后再配置它。现在我想坚持5. – 2010-03-02 05:35:16

+0

为什么不让Fx决定使用多少个线程?这是ThreadPool类的默认设置,它在我的经验中做得很好。 – 2010-03-02 07:49:04

回答

4

我投给了task parallel library/Rx(包含在.NET 4.0,但是下载的3.5):

 var options = new ParallelOptions(); 
     options.MaxDegreeOfParallelism = 5; 

     Parallel.ForEach(GetListOFiles(), options, (file) => 
     { 
      DoStuffWithFile(file); 
     }); 

注意,这将使用多达5个线程,但我已经看到它使用较少。

2

将文件列表分成5个相同大小的列表。然后启动五个线程,并通过ParameterizedThreadStart传递每个单独的较小列表。

但是,由于工作几乎完全受I/O限制,因此此过程不太可能受益于线程。

+0

@Sam:不太确定没有从多线程IO中获益。有文件数据要在内存中复制,操作系统有更好的读取知识并可以优化,磁盘可以支持并行IO(RAID?)等。当然,直到我们实际测量它时才能说出来,所以它现在说这件事还为时过早。 – 2010-03-02 05:23:50

4
+1

使用setmaxthreads不是真的推荐,除非你真的知道你在做什么。您正在限制共享线程池,并且您使用的库可能最终受其影响。 – 2010-03-02 05:26:35

+0

我给了这个-1,因为这通常是不好的做法。 – 2010-03-02 15:13:11

2

虽然这可能不是直接回答你的问题,但似乎一个producer-consumer design将符合您的需求。另外,this可能会有所帮助。

2

我通常这种方法:

声明一个共享整数变量来表示工作线程的数目。 将作业分配给线程时(只需将作业排列到ThreadPool中),增加该值。当一个线程完成作业时,减少该值。

确保整数值的递减或递增为原子。

在作业调度程序中,只有在工作线程数小于最大值的情况下,才能获取作业并分配给线程。否则,等待一个信号(这将由工作线程完成一项工作来触发)。如果你希望事件更简单,让调度器简单地做空循环等待。

好处是最大值是可配置的,它利用了内置的ThreadPool。编写消费者/生产者模型来解决这样一个小问题是很昂贵的。