同时处理几个简单的任务似乎不太合适

本文关键字:任务 简单 处理 几个 | 更新日期: 2023-09-27 18:15:47

我遇到了一个问题,如果我们看一下控制台写命令,每个任务的输出都不像它应该的那样真实。

using System;
using System.Threading.Tasks;
namespace randomTaskTest
{
    class Program
    {
        public static void foo()
        {
            Random rnd = new Random((int)DateTime.Now.Ticks); // I know that I should not cast long to int
            int target = 3;
            int currentNumber = rnd.Next(1, 100);
            int tryCounter = 0;
            while(currentNumber!=target)
            {
                currentNumber = rnd.Next(1, 100);
                tryCounter++;
            }
            Console.WriteLine(tryCounter);
            rnd = null;
        }
        static void Main(string[] args)
        {
            for (int i = 0; i < 30; i++)
                Task.Run(() => { foo(); });
            Console.ReadKey();
        }
    }
}

我把30个任务放在循环中,直到Random类在<1;100>的范围内找到正确的数字。在理想情况下,控制台窗口中的第一个输出条目应该按升序排序,但事实并非如此。

我对这段代码的理解是,当找到一个随机数时,应该尽快将其写入控制台窗口,因为最幸运的随机实例首先离开循环。

输出如下所示:3
18
7
30

而不是
3
7
18
30

等。

当Task的创建时间比Task的执行时间长时,这是不可能避免的,是吗?至少我认为这个任务结束的时间比创建它的时间要少。

同时处理几个简单的任务似乎不太合适

Task API正在后台使用ThreadPool(或其他线程)。哪个线程在何时执行,执行多长时间取决于操作系统如何调度后台线程。

例如:假设你有两个核心,并且你只运行两个任务。两个任务都在执行中,都是5次试验。现在后台的某个系统进程需要做一些计算,因此操作系统必须暂停两个并行运行的任务中的一个。在需要时间的系统进程再次为另一个任务清除道路之前,其他任务现在继续进行500次试验并打印出来,然后另一个任务立即命中目标并打印出6次。

这被称为竞争条件,你不应该依赖于某件事比另一件事早完成,因为操作系统在后台做了很多事情,你永远不能说哪个线程/任务将在哪个确切的时间执行。这是一个难以发现的常见错误来源。: -)

此外,处理器只能同时执行尽可能多的任务,因为它有核心。当发出的任务多于可用的内核时,API要么等待其中一些任务完成,要么暂停其中一些任务,然后稍后恢复。这也会导致每个任务的处理器时间不规律。