gpt4 book ai didi

.net - 为什么TaskFactory.StartNew Task没有立即启动?

转载 作者:行者123 更新时间:2023-12-04 05:20:14 30 4
gpt4 key购买 nike

按照MSDN Documentation TaskFactory.StartNew,它创建并启动一个任务。因此,对于以下代码示例

class Program
{
public static void Main()
{
var t =Task.Factory.StartNew(
() => SomeLongRunningCalculation(10, Display)
);
var t1 = Task.Factory.StartNew(
() => SomeLongRunningCalculation(20, Display)
);
Console.WriteLine("Invoked tasks");
Task.WaitAll(t, t1);
Console.ReadLine();
}

public static void Display(int value)
{
Console.WriteLine(value);
}

public static void SomeLongRunningCalculation(int j, Action<int> callBack)
{
Console.WriteLine("Invoking calculation for {0}", j);
System.Threading.Thread.Sleep(1000);
if (callBack != null)
{
callBack(j + 1);
}
}
}

我的预期输出是

Invoking calculation for 10
Invoking calculation for 20
Invoked tasks
11
21


但是,它正在显示

Invoked tasks
Invoking calculation for 20
Invoking calculation for 10
21
11


我乐意去学
  • 为什么在StartNew之后任务没有立即运行?
  • 我应该怎么做才能获得预期格式的输出?
  • 最佳答案

    在具有单核cpu的计算机上,这很可能会导致结果。或者可能是使用多核cpu的计算机,并且它也在忙于做其他事情。

    创建任务或线程仅会建立允许代码运行的逻辑操作系统结构。如果内核繁忙,则操作系统调度程序不会立即开始执行它,线程必须与计算机上运行的所有其他线程竞争。一个典型的Windows session 大约有一千个。内核每秒产生64次中断,调度程序重新评估正在发生的情况,以查看另一个线程是否应该转弯。任何未阻塞的线程(等待其他线程完成作业,例如读取文件或网络数据包)都可以运行,并且调度程序会选择优先级最高的线程。调度程序中的一些其他代码会修改优先级值,以确保所有线程都有机会。

    机会是这里的关键词。线程调度是不确定的。

    请注意,我从没说过有关Thread或Task或ThreadPool类的事情。他们无权对操作系统调度线程的方式做很多事情。可能的一切是防止线程运行,即线程池调度程序的工作。

    优先级很重要,您可以修改Thread.Priority或Task.Priority属性以影响结果。但是,请注意,操作系统调度程序会根据您使用该属性设置的基本优先级不断调整线程优先级。例如,您不能通过拥有另一个优先级更高的线程来阻止线程运行。

    希望线程以可预测的顺序运行会导致最严重的错误,即线程竞赛错误。第二大僵局是僵局。它们非常难以调试,因为它们取决于时间以及可用的计算机资源和负载。您只能通过编写明确处理该订单的代码来确保获得特定订单。通过使用诸如Mutex或lock关键字之类的线程原语来执行此操作。同样值得注意的是,当您尝试将这样的代码添加到代码段中时,您最终将获得一个不再具有并发性的程序。换句话说,您将最终不再需要Task。线程或任务只有在您负担得起在不可预测的时间运行时才有用。

    关于.net - 为什么TaskFactory.StartNew Task没有立即启动?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10266221/

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