gpt4 book ai didi

c# - Thread.Sleep 是否会阻碍其他线程?

转载 作者:太空狗 更新时间:2023-10-29 17:34:29 32 4
gpt4 key购买 nike

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

static void Main(string[] args)
{
System.Threading.Tasks.Parallel.For(0, 10, (index) =>
{
Action<int> 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 被迫开始在事件线程之间交换内核时,完成的工作更少。线程池管理器不够聪明,无法知道线程正在休眠并且实际上没有执行任何工作。

在双核机器上,您会立即看到前 2 个线程。然后允许额外的线程运行,当线程管理器注意到事件线程没有取得任何进展并且可能被阻塞时,以一秒的间隔一个接一个地运行。释放线程和执行 Console.Write() 调用的顺序是不确定的。

当然这是人为测试,真正的线程是不休眠的。如果您有长时间阻塞的线程,例如等待 I/O 请求完成,那么使用线程池线程(任务)并不是最佳解决方案。

关于c# - Thread.Sleep 是否会阻碍其他线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6195672/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com