Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 4.0 WaitAll()未按预期执行_C# 4.0_Task - Fatal编程技术网

C# 4.0 WaitAll()未按预期执行

C# 4.0 WaitAll()未按预期执行,c#-4.0,task,C# 4.0,Task,我已经编写了以下模拟代码作为我所看到的示例。我希望任务能在一秒钟多一点的时间内完成,因为它们都需要等待一秒钟。相反,完成任务大约需要41秒。为什么它在41秒内完成,而不是预期的1秒 Task[] tasks = new Task[1000]; DateTime startTime = DateTime.Now; for (int i = 0; i < 1000; i++) { // allocate room in the list for the items we are goi

我已经编写了以下模拟代码作为我所看到的示例。我希望任务能在一秒钟多一点的时间内完成,因为它们都需要等待一秒钟。相反,完成任务大约需要41秒。为什么它在41秒内完成,而不是预期的1秒

Task[] tasks = new Task[1000];
DateTime startTime = DateTime.Now;
for (int i = 0; i < 1000; i++)
{
    // allocate room in the list for the items we are going to insert
    Task task = Task.Factory.StartNew(() => Thread.Sleep(1000));
    tasks[i] = task;
}
Task.WaitAll(tasks);
DateTime endTime = DateTime.Now;

TimeSpan span = endTime - startTime;
Task[]tasks=新任务[1000];
DateTime startTime=DateTime.Now;
对于(int i=0;i<1000;i++)
{
//在列表中为我们要插入的项目分配空间
Task Task=Task.Factory.StartNew(()=>Thread.Sleep(1000));
任务[i]=任务;
}
Task.WaitAll(任务);
DateTime endTime=DateTime.Now;
时间跨度=结束时间-开始时间;

您的每个任务都会被推送到线程池中,但这与为每个任务分配自己的线程并立即运行它不同。线程池不会使用无限数量的线程,因为您没有无限数量的CPU内核。同时运行1000个线程通常会比较慢,因为当许多线程争用少数可用内核时,所有上下文都会切换

相反,线程池尝试选择一个最佳的线程数,以在保持所有内容移动和不具有太多上下文切换之间取得平衡,从而获得尽可能好的(或至少非常好的)吞吐量。1000个任务每运行1秒除以约40秒意味着池中有25个线程

在这种情况下,您可能可以使用更高的线程数安全地运行,因为每个任务所做的只是睡眠。但threadpool不知道这一点。它期望您能够在CPU中完成这些任务的实际工作,并据此进行了设计。即使在这里,也要记住,即使只有25个线程,您也已经有了整整一秒钟的开销


最后,我经常遇到这样的代码,这些代码使用多个线程来分割CPU上的工作,结果发现真正的瓶颈是磁盘或网络I/O。始终值得提醒自己,磁盘的速度非常快,如果您试图分割来自文件、网络流或数据库的工作,您的CPU可能比您的数据源快很多,并且您可能不会获得太多(如果有的话)。这并不意味着“停止”,但它确实意味着您还需要花时间来衡量,以确保这种额外的代码复杂性是值得的。

您的每个任务都被推送到线程池中,但这与为每个任务分配自己的线程并立即运行它并不相同。线程池不会使用无限数量的线程,因为您没有无限数量的CPU内核。同时运行1000个线程通常会比较慢,因为当许多线程争用少数可用内核时,所有上下文都会切换

相反,线程池尝试选择一个最佳的线程数,以在保持所有内容移动和不具有太多上下文切换之间取得平衡,从而获得尽可能好的(或至少非常好的)吞吐量。1000个任务每运行1秒除以约40秒意味着池中有25个线程

在这种情况下,您可能可以使用更高的线程数安全地运行,因为每个任务所做的只是睡眠。但threadpool不知道这一点。它期望您能够在CPU中完成这些任务的实际工作,并据此进行了设计。即使在这里,也要记住,即使只有25个线程,您也已经有了整整一秒钟的开销

最后,我经常遇到这样的代码,这些代码使用多个线程来分割CPU上的工作,结果发现真正的瓶颈是磁盘或网络I/O。始终值得提醒自己,磁盘的速度非常快,如果您试图分割来自文件、网络流或数据库的工作,您的CPU可能比您的数据源快很多,并且您可能不会获得太多(如果有的话)。这并不意味着“停止”,但它确实意味着您还需要花时间来衡量,以确保这种额外的代码复杂性是值得的