C#异常:线程间操作无效: 从不是创建控件“xxx”的线程访问它

作者:袖梨 2022-06-25

C# WinForm开发中,这是一个比较常见的异常:线程间操作无效,从不是创建控件“xxx”的线程访问它。这个异常来源于.NET2的一个限制:工作线程不能访问窗口线程创建的控件。解决方法主要有两种,一种是在窗口线程中设置CheckForIllegalCrossThreadCalls = false ;另一种方式比较麻烦,使用委托的方式调用Invoke方法。

比如窗口中有一个button1,我要新建一个线程访问到button1。第一种方式是:

 代码如下 复制代码

this.button1.Enabled = false;
new Thread(new ThreadStart(delegate()
{
    try {
      
        CheckForIllegalCrossThreadCalls = false;
        // 直接设置会引发异常:线程间操作无效,从不创建控件的线程访问它
        this.button1.Enabled = true;

    }catch(Exception ex)
    {
        MessageBox.Show(ex.ToString());
    }
               
})).

Start();使用委托

 代码如下 复制代码

///


/// 声明委托
///

///
///
private delegate void _SetButtonState(Button button,bool state);

///


/// 设置Button的状态
///

/// 按钮
///
private void SetButtonState(Button button,bool state)
{
    // 对于该控件的请求来自于创建该控件所在线程以外的线程
    if (button.InvokeRequired)
    {
        _SetButtonState _set = new _SetButtonState(delegate(Button _button, bool _state)
            {
                _button.Enabled = _state;
            });
        this.Invoke(_set, button, state);
    }
    else
    {
        button.Enabled = state;
    }

  然后再从新线程访问控件button1

 代码如下 复制代码

this.button1.Enabled = false;
new Thread(new ThreadStart(delegate()
{
    try {
        // 直接设置会引发异常:线程间操作无效,从不创建控件的线程访问它
        // CheckForIllegalCrossThreadCalls = false;
        // this.button1.Enabled = true;

        // 用委托的方式
        SetButtonState(button1,true);
    }catch(Exception ex)
    {
        MessageBox.Show(ex.ToString());
    }
               
})).Start();

相关文章

精彩推荐