C# 线程起始顺序不一致



我想知道为什么线程起始顺序与执行顺序不一致。

这是我的代码。

class Test
{
public Test()
{
Thread t1 = new Thread(new ThreadStart(Run));
Thread.CurrentThread.Name = "Primary Thread";
t1.Name = "Secondary Thread";
t1.Start();
Run();
}
void Run()
{
Debug.WriteLine($"Thread#{Thread.CurrentThread.Name}: Begin");
Thread.Sleep(5000);
Debug.WriteLine($"Thread#{Thread.CurrentThread.Name}: End");
}
}  

t1线程的启动时间早于代码中的Main Thread。尽管如此,Main Thread还是首先执行。 为什么会这样?

提前谢谢。

在编写更多的多线程代码之前,您需要学习多线程编码的基本规则。

在单线程代码中,你可以假设东西保持不变,除非有什么东西导致它改变。 在多线程代码中,你必须假设东西正在改变,除非有什么东西保持相同。

您的示例是该一般规则的特定情况。在这种情况下,正在改变的"东西"是观察到副作用的顺序。 你几乎没有做任何事情来保持这些"东西"的静止,所以它可能会任意改变。

C# 规范中记录了非常具体、明确的规则,说明在多线程程序中必须按特定顺序观察哪些副作用;这是一个非常短的列表,程序中的副作用不在该列表中。

允许两个线程以任何顺序运行它们的副作用,但实际上比这更糟糕。在 C# 中,不需要多个线程来提供从每个线程观察到副作用的一致顺序

实际上,在您的示例中,您观察到选择了对 Debug.Write 的特定调用顺序。 正在运行的程序可以选择错这些副作用的任何顺序;您只能保证,在同一线程上End之后,您不会在一个线程上看到Begin

您的问题是:

为什么会这样?

但正如我们所看到的,这是一个错误的问题。 观察到的行为是允许发生的,而且确实发生了,所以问为什么会发生对你没有帮助。我想你想问的问题是

如何强制两个线程以相对于彼此的特定顺序运行它们的副作用?

但这也不是正确的问题。 正确的问题是:

如何使用异步安全有效地解决特定的性能问题?

该问题的答案取决于实际问题,创建线程通常不是正确的解决方案。理想情况下,仅当有 CPU 密集型任务要解决,并且线程可以接管空闲 CPU 时,才创建线程。 通常,涉及异步的性能问题最好在单个线程上解决,await.

如果你用简单的英语表达,这个结果会更有意义:

My To-Do List:
Instruct Bob to go off and do something
Begin doing something yourself

。你得到的结果是,鲍勃在你开始工作之前就开始了他的工作。 所以? 没有理由认为鲍勃在入门时会比你更快/更慢。 鲍勃只是打败了你。

你的代码也是如此。 你告诉一个单独的任务开始,然后启动一个功能。 两位代码正在做两件独立的事情 - 没有任何理由怀疑一个应该比另一个开始得更快。

最新更新