什么时候我允许跨线程访问,什么时候不允许?

kdh*_*kdh 2 c# multithreading

似乎C#有时会抛出跨线程操作的异常.例如,您可以尝试在Windows窗体程序中运行此示例代码:

    public Form1()
    {
        InitializeComponent();
        Thread setTextT = new Thread(TextSetter);
        setTextT.Start();
    }

    private void TextSetter()
    {
        //Thread.Sleep(4000);
        textBox1.Text = "Hello World";
    }
Run Code Online (Sandbox Code Playgroud)

它没有抛出任何异常,一切似乎都运行正常.现在,当您取消注释Thread.Sleep行时,它将为尝试的跨线程访问抛出异常.

为什么会这样?

Sco*_*ain 5

这是因为交叉线程检查仅在创建窗口句柄之后发生,因为您要检查的是对窗口句柄的跨线程访问.当您没有睡眠时,代码在第一次显示控件之前运行得足够快(第一次显示控件时会创建句柄).

知道是否需要注意UI控件的跨线程访问的简单方法只是检查InvokeRequired,如果确实如此,则需要调用Invoke(或者BeginInvoke如果您不想等待它完成)才能启用创建控件的线程.

  • 这就是为什么你应该在窗体的Load事件中启动线程,而不是从构造函数启动.这样,您将获得更一致的行为. (3认同)