zoukankan      html  css  js  c++  java
  • 从.NET 1.1 升级到.NET 4.0 遇到 线程间操作无效: 从不是创建控件 [XX] 的线程访问它.

    有两种方式解决 
    1.在窗体构造函数中写Control.CheckForIllegalCrossThreadCalls =false;
    2.使用Invoke等委托函数

    问题原因是 .NET2.0 以后拒绝多线程访问空间,避免空间造成死锁。以前Control.CheckForIllegalCrossThreadCalls =false;默认就是这样,现在默认为true。
    如果不会好几个线程同时操作一个控件用方法1就可以。如果存在多个线程一起操作控件使用方法2

    我们在用线程操作的时候,可能会出现异常:线程间操作无效: 从不是创建控件richTextBox1的线程访问它。因为windows窗体控件不是线程安全的,如果几个线程操作某一控件的状态,可能会使该控件的状态不一致,出现争用或死锁状态。这种情况有以下解决办法:

    1. 可以在load时将CheckForIllegalCrossThreadCalls 属性的值设置为 false 。这样进行非安全线程访问时,运行环境就不去检验它是否是线程安全的。但是不推荐这种方法。

    2. 利用委托机制实现线程安全。第二种方法就是微软建议采用的跨线程调用的一种通用方法,就是使用代理来实现,就是将你所要操作的代码放到一个代理中,然后将这个代理交给创建这个控件的线程来执行你的代码。

         private delegate void richTextBoxCallBack();
            //建立一个委托
    
            public void server()
            {
                richTextBoxCallBack callback = delegate()//使用委托
                {
                    string ip = getIP();//得到ip地址
                    try
                    {
                        //获取txt文件的端口号
                        StreamReader smReader = new StreamReader(path, System.Text.Encoding.UTF8);//设置路径  
                        string line;
                        while ((line = smReader.ReadLine()) != null)
                        {
                            //string[] arrStr = line.Split('|');     //分割符 “|”      
                            port = Int32.Parse(line.Trim().ToString());
                            //  MessageBox.Show(port.ToString());
                        }
                        smReader.Close();
                        smReader.Dispose();
                        IPAddress ipAddress = IPAddress.Parse(ip);
                        //创建服务器的套接字
                        listener = new TcpListener(ipAddress, port);
                        //开始监听服务器端口
                        listener.Start(13);
    
                        //打出提示的信息
                        this.richTextBox1.AppendText("Socket服务器已经启动,正在监听IP" +
                            ip + " 端口号:" + port + "/n");     //从不是创建它的线程访问它的错误???
                        //启动一个新的线程,执行方法this.StartSocketListen,
                        //以便在一个独立的进程中执行确认与客户端Socket连接的操作
                        SocketServiceFlag = true;//服务开始
                        Thread thread = new Thread(new ThreadStart(this.StartSocketListen));
                        thread.Start();
                        this.button1.Enabled = false;
                        this.button2.Enabled = true;
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("服务器启动错误!!" + ex.Message);
                    }
                };
                richTextBox1.Invoke(callback);
                 
            }

    建立一个委托 private delegate void richTextBoxCallBack(); 

    然后使用委托 richTextBoxCallBack callback = delegate(){}; //使用委托, 声明一个委托类型的变量callback ,{}之间的代码还是原来的方法的代码,最后richTextBox1.Invoke(callback);完成对该控件委托调用

  • 相关阅读:
    Windows Server 2008 R2 服务器系统安装及配置全过程图文详解
    c#多线程
    DevExpress之TreeList控件用作导航使用说明
    Windows操作系统下搭建Git服务器和客户端。
    D^3CTF 2021 8-bit-pub
    shiro-1.2.4反序列化分析踩坑
    *CTF2021 oh-my-bet
    无线网络密码破解初体验
    瑞昱rtl819x-SDK-v3.4.14b的watchdog分析
    RC4加密算法
  • 原文地址:https://www.cnblogs.com/ShaYeBlog/p/3449716.html
Copyright © 2011-2022 走看看