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# 规范中记录了非常具体、清晰的规则,这些规则涉及在多线程程序中必须以特定顺序观察哪些副作用;这是一个非常短的列表,您程序中的副作用不在该列表中。

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

实际上,在您的示例中,您观察到选择了 Debug.Write 的特定调用顺序。运行程序可以选择任意顺序交错那些副作用;所有你保证的是,你不会看到一个Begin在一个线程之后End同一个线程上。

你的问题是:

为什么会这样?

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

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

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

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

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章