任务等待任意条件

5
我发现一些代码使用了Task.WaitAny方法。
Task<int>[] tasks = new Task<int>[3];

tasks[0] = Task.Run(() => { Thread.Sleep(2000); return 1; });
tasks[1] = Task.Run(() => { Thread.Sleep(1000); return 2; });
tasks[2] = Task.Run(() => { Thread.Sleep(3000); return 3; });

while (tasks.Length > 0) {
    int i = Task.WaitAny(tasks);
    Task<int> completedTask = tasks[i];

    Console.WriteLine(completedTask.Result);

    var temp = tasks.ToList();
    temp.RemoveAt(i);
    tasks = temp.ToArray();
}

代码运行正常,结果为 2 1 3。
当我尝试更改睡眠间隔时。
tasks[0] = Task.Run(() => { Thread.Sleep(2000); return 1; });
tasks[1] = Task.Run(() => { Thread.Sleep(1000); return 2; });
tasks[2] = Task.Run(() => { Thread.Sleep(1000); return 3; });

while (tasks.Length > 0) {
    int i = Task.WaitAny(tasks);
    Task<int> completedTask = tasks[i];

    Console.WriteLine(completedTask.Result);

    var temp = tasks.ToList();
    temp.RemoveAt(i);
    tasks = temp.ToArray();
}

尽管任务二的睡眠时间最短且应该首先被移除,但我还是得到了123。

底层发生了什么?


1
可能是一些时间问题。将睡眠间隔增加10倍以排除这种可能性。 - usr
4
无法复现 - 我得到了“(暂停)2,3(暂停)1”或“(暂停)3,2(暂停)1”- 正如预期的那样。你的电脑有多少个内核?如果你只有一个单核处理器,可能需要一些时间来启动工作线程。 - Marc Gravell
1
顺便问一下,1000、1000是打错了吗?应该有一个应该是3000吧? - Marc Gravell
1
@user1648371这是否意味着您正在虚拟单核计算机上运行此代码?如果是这种情况,我认为Marc是正确的:ThreadPool会快速创建与您核心数相同数量的线程,但其他线程会慢慢创建。 - svick
1
我检查了VMWare选项,发现Windows只使用了一个处理器。将该数字增加后问题得到解决。请将此回答整理好,我会接受它。 - MaPi
显示剩余4条评论
1个回答

1

Thread.Sleep在暂停程序指定的毫秒数方面相当准确。

Thread.Sleep(1000)表示任务将在1000毫秒后可执行。

但是,从所有可用任务中首先执行哪个任务是由任务计划程序决定的,它根据线程池中的线程数量和许多其他因素决定任务的执行顺序。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接