zoukankan      html  css  js  c++  java
  • C# .NET 在一个线程中访问另一个线程的控件 方法汇总 (转载)

    .NET 不允许在一个线程中直接访问另一个线程创建的控件,会引发异常:线程间操作无效,从不是创建控件XXX的线程访问它。

    Windows 窗体中的控件被绑定到特定的线程,不具备线程安全性。

    如果从另一个线程调用控件的方法,那么必须使用控件的一个 Invoke 方法来将调用封送到适当的线程。

    本文以一个线程去改变另一个线程的 Label(lb_Name) 的 Text 属性为例,实现不同线程间控件的访问。

    1:声明一个委托,方法签名为一个 string

    public delegate void SetText(string text);

    2:定义一个方法,用来改变 Lbale 的 Text,不同线程都可以调用,此方法可以带上参数,就可以不用匿名方法了,委托方法就是此方法

    /// <summary>
    /// Invoke 方式访问控件,判断控件是不是当前线程所创建
    /// </summary>
    private void SetLbText()
    {
        // 如果返回 True ,则访问控件的线程不是创建控件的线程
        if (lb_Name.InvokeRequired)
        {
            // 实例一个委托,匿名方法,
            SetText st = new SetText(delegate(string text)
            {
                // 改变 Label 的 Text
                lb_Name.Text = text;
            });
     
            // 把调用权交给创建控件的线程,带上参数
            lb_Name.Invoke(st, "我是另一个线程---Invoke 方式");
        }
        else
        {
            lb_Name.Text = "此控件是我创建的---Invoke 方式";
        }
    }

    3:新开一个线程,执行以上方法:

    Thread t = new Thread(new ThreadStart(SetLbText));
    t.Start();

    4:直接访问,将访问失败:

    // 新开一个线程,使用 ThreadStart 委托,匿名方法
    Thread t = new Thread(new ThreadStart(delegate()
    {
        // 直接调用
        try
        {
            lb_Name.Text = "我是另一个线程";
        }
        catch (Exception ex)
        {
            // 不同线程间,无法访问
            MessageBox.Show(ex.Message);
        }
    }));
     
    //启动线程
    t.Start();

     方法4 :

     delegate void SetLableText(Label lb, string str);


    void SetLabelText(Label lb, string str)

            {

                
    if (lb.InvokeRequired)

                    lb.Invoke(
    new SetLableText(SetLabelText),lb,str);

                
    else

                    lb.Text 
    = str;

            }

    方法5:

    System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false; 

    方法六:

    Invoke(new Action(()=>{lb_Name.Text = "我是另一个线程";})); 

  • 相关阅读:
    2019.6.20刷题统计
    36 线程 队列 守护线程 互斥锁 死锁 可重入锁 信号量
    35 守护进程 互斥锁 IPC 共享内存 的方式 生产者消费者模型
    34 进程 pid ppid 并发与并行,阻塞与非阻塞 join函数 process对象 孤儿进程与僵尸进程
    33 udp 域名 进程
    32 粘包 文件传输
    31 socket客户端. 服务器 异常 语法
    30 网络编程
    29 元类 异常
    26 封装 反射 常用内置函数
  • 原文地址:https://www.cnblogs.com/invinboy/p/2003696.html
Copyright © 2011-2022 走看看