VS2005 c# 多线程:如何启动10个线程

3

如何以类似于for循环的方式启动10个线程来执行一个处理密集型方法,代码示例将非常有帮助。

for (int i = 0; i<=10; i++) //10 threads are intended.
{
    LongRunningMethod();
}

7
请注意,您在此创建了11个线程。这只是一个细节提示。 - H H
6个回答

5

ThreadPool.QueueUserWorkItem


请确保您在其中有足够的MaxThreads(在这种情况下为10),否则您的某些线程将在队列中等待。 - Noam Gal
2
线程池在您的应用程序和CLR库之间共享使用。在某些情况下,使用它可能会对应用程序产生负面影响。 - Franci Penov
4
我们无法确定 LongRunningMethod 函数在做什么,但考虑到其名称,使用线程池线程可能不是最优的选择。 - Brian Rasmussen
甚至可以拥有超过10个线程,但同时只有10个会运行。 - Athiwat Chunlakhan

2

如果您不想使用线程池,可以创建并启动一个新线程。

new Thread( delegate() { LongRunningMethod(); } ).Start();

2
使用线程池线程来执行长时间运行的任务可能会对您的应用程序和CLR性能产生影响。 - Franci Penov
1
不使用线程池的原因在“使用线程池的限制”下有描述。 - Harv
线程池可以回收线程,从而避免创建新线程的开销。正如Franci所说,避免使用它的主要原因是为了长时间运行的后台线程--在这种情况下,生成新线程将会产生初始开销,但会使池线程空闲以供短作业使用。 - STW
2
OP提到了VS2005,也就是C#2。因此,lambda表达式并没有什么帮助。 - H H
啊,忘了那个了,改成 C# 委托语法。 - Chris Chilvers

2

正如其他答案中所提到的,您可以使用ThreadPool.QueueUserWorkItem将作业调度到线程池中的一个线程上或创建一个新的显式Thread实例来处理该工作。有关创建线程的各种方法的详细信息,请参阅MSDN线程教程

您选择使用哪种方法可能会对您的应用程序和CLR的性能和行为产生一定的影响。有关更多详细信息,请阅读C#中何时使用线程池


1
使用Action作为委托,为每个长时间运行的方法调用创建一个新线程。
Action newThread = new Action(LongRunningMethod);

// Call Async which is a new thread
newThread.BeginInvoke(null, null);

没有模板的Action只存在于.NET 3.5中,对于.NET 2.0,您必须声明一个委托。

public delegate void NoParametersMethod();

NoParametersMethodnewThread = new NoParametersMethod(LongRunningMethod);

// Call Async which is a new thread
newThread.BeginInvoke(null, null);

1
Delegate.BeginInvoke() 使用远程消息系统并产生一定的开销,而使用 ThreadPool.QueueUserWorkItem 可以避免这种开销。 - STW

1
这里的答案和评论可能有些分歧,这是因为首先要做的是检查您的LongRunningMethod()是否适合线程池。如果适合,则使用线程池是最佳选择(开销低,具有一些基本的负载平衡)。
否则,请使用Thread和ThreadStart:
ThreadStart starter = new ThreadStart(LongRun);

for (int i = 1; i <= 10; i++) // 10 threads are intended, note the i=1
{    
    Thread t = new Thread(starter);
    t.Start();
}

注意1:还存在一个ParameterizedThreadStart类。

注意2:您不能将其扩展到i < 100或其他值,您需要限制最大线程数。线程池已经做到了。

来自MSDN:

何时不使用线程池线程

有几种情况下,创建和管理自己的线程而不是使用线程池线程是合适的:

  • 您需要一个前台线程。
  • 您需要一个特定优先级的线程。
  • 您有一些任务会导致线程长时间阻塞。线程池有最大线程数,因此大量阻塞的线程池线程可能会阻止任务启动。
  • 您需要将线程放入单线程公寓。所有ThreadPool线程都在多线程公寓中。
  • 您需要将稳定的身份与线程关联,或者专门为任务分配一个线程。
请注意,MSDN没有说明“长时间”是多久。我会尝试说,当您的任务需要>= 0.5秒时,您可能需要开始查看单独的线程。创建线程的开销变得微不足道。但这取决于很多因素。

0

像这样简单的东西...

var threads    = new List<Thread>();
var numThreads = 10;

for( int i = 0; i < numThreads; i++ )
{
  threads.Add( new Thread( () => DoWork() ) );
  threads[i].Name = i.ToString();
  threads[i].Start();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接