【问题标题】:Threads not starting same time线程不同时开始
【发布时间】:2019-02-27 14:41:03
【问题描述】:

我知道有很多关于这个主题的问题,我已经查看了所有问题,但找不到可行的解决方案。

我在 WPF 应用程序中同时启动 10 个线程。

前四个线程同时启动,但其他作业开始滞后约 5-10 秒。我在下面分享测试数据。

我该如何解决这个问题?

private void DoParallel()
{
    for (int i = 0; i < 10; i++)
    {
         Task.Factory.StartNew(() =>
          {
            Console.WriteLine(DateTime.Now.ToString());
            DoSomeWork();
          });
        }
    }
}
  • 27.02.2019 17:31:33
  • 27.02.2019 17:31:33
  • 27.02.2019 17:31:33
  • 27.02.2019 17:31:33
  • 27.02.2019 17:31:35
  • 27.02.2019 17:31:40
  • 27.02.2019 17:31:46
  • 27.02.2019 17:31:52
  • 27.02.2019 17:32:00
  • 27.02.2019 17:32:02

【问题讨论】:

  • DoSomeWork 是否在做一些非常繁重的计算?
  • DoSomeWork 大约需要 10 秒。我正在打电话给肥皂服务。
  • 这取决于很多事情。我建议你读一本关于 TPL 的书。
  • 根据DoSomeWork 所做的所有 CPU 可能正忙于让其他线程等待。我们应该怎么知道?
  • 您正在观察 ThreadPool 在具有 4 个 cpu 内核的机器上的行为。您可以尝试使用 TaskCreationOptions.LongRunning 来告诉 Task 类 DoSomeWork() 需要一段时间。这是一个极端情况,它只需要比太长一点的时间,所以你必须检查你是否真的领先。注意在任务管理器的进程选项卡中可见的 cpu 负载。如果现在接近 100%,那么不花钱你就不会领先。

标签: c# multithreading task


【解决方案1】:

这是设计使然。默认的TaskScheduler 使用的是.NET ThreadPool,它可能已经饱和,您对其控制有限。

如果您愿意,您可以创建自己的TaskScheduler 来更改此行为。例如,如果需要,您可以创建一个启动单独线程的线程。

如果您的代码触发的任务比已经执行的更多,这种行为会变得更加明显:

private void DoParallel()
{
    //This will over-saturate the ThreadPool unless you use your own TaskScheduler
    for (int i = 0; i < 100; i++)
    {
         Task.Factory.StartNew(() =>
          {
            Console.WriteLine(DateTime.Now.ToString());
            DoSomeWork();
          });
        }
    }
}

【讨论】:

  • 如何创建自己的TaskScheduler
  • @ErhanUrun 这个link 有一个完整的代码示例,说明如何实现自定义TaskScheduler。简而言之,您需要对其进行子类化。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-05-10
  • 2023-03-16
  • 1970-01-01
  • 2023-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多