gpt4 book ai didi

c# - Thread.Sleep(0) 在 .NET Core 3.1 上没有按预期工作

转载 作者:行者123 更新时间:2023-12-03 12:44:57 24 4
gpt4 key购买 nike

因此,我正在根据以下书籍学习 .NET Thread 类:考试引用 70-483:C# 编程,我注意到一些我不知道为什么会发生或是否应该发生的事情。

这本书在第 4 页给我这部分代码:

public static class Program
{
public static void ThreadMethod()
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine("ThreadProc: {0}", i);
Thread.Sleep(0);
}
}
public static void Main()
{
Thread t = new Thread(new ThreadStart(ThreadMethod));
t.Start();
for (int i = 0; i < 4; i++)
{
Console.WriteLine("Main thread: Do some work.");
Thread.Sleep(0);
}
t.Join();
}
}

预期结果如下所示,因为在每个 Thread.Sleep(0) 处,当前线程退出并继续处理队列中的下一个线程:

// Main thread: Do some work.  
// ThreadProc: 0
// Main thread: Do some work.
// ThreadProc: 1
// Main thread: Do some work.
// ThreadProc: 2
// Main thread: Do some work.
// ThreadProc: 3
// ThreadProc: 4
// ThreadProc: 5
// ThreadProc: 6
// ThreadProc: 7
// ThreadProc: 8
// ThreadProc: 9

但是当我构建我的版本时,它没有按预期工作,即使我复制粘贴代码并在我的机器上运行,每次执行程序时它都会给出这个结果,具有相同的上面的代码:

// Main thread: Do some work.  
// ThreadProc: 0
// ThreadProc: 1
// ThreadProc: 2
// ThreadProc: 3
// ThreadProc: 4
// ThreadProc: 5
// ThreadProc: 6
// ThreadProc: 7
// ThreadProc: 8
// ThreadProc: 9
// Main thread: Do some work.
// Main thread: Do some work.
// Main thread: Do some work.

如您所见,它似乎进入了副线程,当我调用 Thread.Sleep(0) 方法时,它没有按应有的方式返回主线程,而是继续在副线程上工作,直到它完成.

作为解决此问题的方法,我使用 Random 类生成一个介于 100 和 500 之间的随机数以传递给 Thread.Sleep() 方法,它开始按预期工作:

public static class Program
{
public static void ThreadMethod()
{
var rand = new Random();
for (int i = 0; i < 10; i++)
{
Console.WriteLine("ThreadProc: {0}", i);
Thread.Sleep(rand.Next(100, 500));
}
}
public static void Main()
{
Thread t = new Thread(new ThreadStart(ThreadMethod));
t.Start();
var rand = new Random();
for (int i = 0; i < 4; i++)
{
Console.WriteLine("Main thread: Do some work.");
Thread.Sleep(rand.Next(100, 500));
}
t.Join();
}
}

结果如下:

// Main thread: Do some work.  
// ThreadProc: 0
// ThreadProc: 1
// ThreadProc: 2
// Main thread: Do some work.
// ThreadProc: 3
// Main thread: Do some work.
// ThreadProc: 4
// Main thread: Do some work.
// ThreadProc: 5
// ThreadProc: 6
// ThreadProc: 7
// ThreadProc: 8
// ThreadProc: 9

我不认为这本书是在.NET Core框架上写的,我认为这个“问题”可能是由这两个框架之间的同步上下文变化引起的。我检查了两个线程的优先级,并设置为默认的“正常”。

有人知道为什么会这样吗?

最佳答案

在此示例中,您不会看到 .net framework 和 .net core 之间的任何行为差异。

这本书是在大多数消费类 CPU 都是单核的时代写成的。对于单核 CPU,一次只能调度一个线程,因此样本的输出是可预测的。

如今,几乎所有的 CPU 都有多个内核,这意味着可以同时调度多个线程。这使得程序的输出不可预测,并且不受调用 Thread.Sleep(0) 的影响。

在现代硬件上获得书中描述的行为的一种方法是设置进程的亲和性,使其在单核上运行:

> start /affinity 1 CoreConsoleApp1.exe

通过这样做,我得到了预期的交错输出:

ThreadProc: 0
Main thread: Do some work.
ThreadProc: 1
Main thread: Do some work.
ThreadProc: 2
Main thread: Do some work.
ThreadProc: 3
Main thread: Do some work.
ThreadProc: 4
ThreadProc: 5
ThreadProc: 6
ThreadProc: 7
ThreadProc: 8
ThreadProc: 9

关于c# - Thread.Sleep(0) 在 .NET Core 3.1 上没有按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64200401/

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