Thread.Sleep会妨碍其他线程吗?

这是一个控制台程序,希望10个线程批量启动,等待5秒,然后批量停止。

static void Main(string[] args) { System.Threading.Tasks.Parallel.For(0, 10, (index) => { Action act = (i) => { Console.Write("start {0} ", i); Thread.Sleep(5000); }; act.BeginInvoke(index, OnTaskComplete, index); }); Console.ReadKey(); } static void OnTaskComplete(IAsyncResult res) { Console.Write("finish {0} ", res.AsyncState); } 

但结果并不是我所期望的,10个线程一个接一个地慢慢开始(大约1秒间隔),甚至一些“完成”在一些“开始”之前出现。

注释掉Thread.Sleep时,所有线程都在flash中开始和结束。

Thread.Sleep会影响其他线程吗? 无论如何要做一个纯粹的空闲时间?

/ – – – – – – – – – – – – – – -编辑 – – – – – – – – – – ———-

同样的问题也发生在:

 static void Main(string[] args) { System.Threading.Tasks.Parallel.For(0, 10, (index) => { Console.Write("start {0} ", index); Thread.Sleep(5000); Console.Write("fnish {0} ", index); }); Console.ReadKey(); } 

– – – – – – – – – – – 编辑 – – – – – – – – – – – –

最后我找到了一种替代thread.sleep的可爱方法

 static void Main(string[] args) { System.Threading.Tasks.Parallel.For(0, 10, (index) => { Console.Write("start {0} ", index); var t1 = new System.Threading.Timer(new TimerCallback(MyTimerCallback), index, 5000, 0); }); Console.ReadKey(); } static void MyTimerCallback(object o) { Console.Write("Timer callbacked "); } 

这是设计的。 您正在看到线程池管理器尝试将有限数量的线程保持在执行状态。 重要的是确保您的程序没有运行比您的机器具有cpu内核更多的线程。 当Windows被迫开始在活动线程之间交换核心时,效率低下,工作量减少。 线程池管理器不够智能,无法知道线程正在hibernate而实际上没有执行任何工作。

在双核机器上,您将看到前两个线程立即开始。 然后,当线程管理器注意到活动线程没有取得任何进展并且可能被阻塞时,允许其他线程逐个运行,间隔为1秒。 释放线程并执行Console.Write()调用的顺序不确定。

这是一个人工测试当然,真正的线程不会睡觉。 如果您有长时间阻塞的线程,等待I / O请求完成,例如使用线程池线程(任务)并不是最好的解决方案。

TaskCreationOptions.LongRunning将“删除”ThreadPool限制。
我不知道为Parallel.For指定TaskCreationOptions.LongRunning的简单方法。
但是,您可以使用Task类实现相同的效果:

 Action action = i => { Console.Write("start {0} ", i); Thread.Sleep(5000); Console.Write("finish {0} ", i); }; var tasks = Enumerable.Range(0, 100) .Select(arg => Task.Factory.StartNew(() => action(arg), TaskCreationOptions.LongRunning)) .ToArray(); Task.WaitAll(tasks); 

如果没有TaskCreationOptions.LongRunning ,它将以与Parallel.For完全相同的方式运行。

我稍微更新了代码,以便在写入控制台时显示ThreadID:

 Console.WriteLine("start index:{0} thread id:{1} Time:{2} ", index, Thread.CurrentThread.ManagedThreadId.ToString(), DateTime.Now.ToLongTimeString()); Thread.Sleep(5000); ConsoleWriteLine("finish index:{0} thread id:{1} Time:{2} ", index, Thread.CurrentThread.ManagedThreadId.ToString(), DateTime.Now.ToLongTimeString()); 

我的机器是双核心,这是我得到的输出。 这应该让你了解发生了什么。 请记住,循环可能并不总是按顺序运行,即。 0到9,并行,它抓取你的数组的一大块并通过lambda运行每个项目。

输出:

 start index:1 thread id:11 Time:11:07:17 PM start index:0 thread id:9 Time:11:07:17 PM start index:5 thread id:10 Time:11:07:17 PM start index:6 thread id:12 Time:11:07:18 PM start index:2 thread id:13 Time:11:07:19 PM start index:7 thread id:14 Time:11:07:20 PM start index:3 thread id:15 Time:11:07:21 PM start index:8 thread id:16 Time:11:07:22 PM finish index:0 thread id:9 Time:11:07:22 PM start index:4 thread id:9 Time:11:07:22 PM finish index:1 thread id:11 Time:11:07:22 PM start index:9 thread id:11 Time:11:07:22 PM finish index:5 thread id:10 Time:11:07:22 PM finish index:6 thread id:12 Time:11:07:23 PM finish index:2 thread id:13 Time:11:07:24 PM finish index:7 thread id:14 Time:11:07:25 PM finish index:3 thread id:15 Time:11:07:26 PM finish index:8 thread id:16 Time:11:07:27 PM finish index:4 thread id:9 Time:11:07:27 PM finish index:9 thread id:11 Time:11:07:27 PM