Windows Form线程安全调用

 

  • 线程调用控件过程中出现了异常?

    有如下代码,在新建的线程中调用textBox的方法时候,调试器报出异常。

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Net.Sockets;
    using System.Net;
    using System.Threading;
    
    namespace _01_socketclient
    {
    	public partial class SocketClient : Form
    	{
    		Thread receiveThread = null;	//接受线程
    		
    		public SocketClient()
    		{
    			InitializeComponent();
    		}
    
    		private void btnConnection_Click(object sender, EventArgs e)
    		{
    			//实例接收线程
    			receiveThread = new Thread(new ThreadStart(RecevieThread));
    			//设置为后台线程
    			receiveThread.IsBackground = true;
    			//启动接受线程
    			receiveThread.Start();
    		}
    
    		/// <summary>
    		/// 显示文本信息
    		/// </summary>
    		/// <param name="msg"></param>
    		private void ShowMsg(string msg)
    		{
    			txtShow.AppendText(msg + "\r\n");
    		}
    
    		/// <summary>
    		/// 接收线程执行方法
    		/// </summary>
    		private void RecevieThread()
    		{
    			string strMsg = "hello world"
    			ShowMsg(strMsg);
    		}
    
    	}
    }
    

     

  • 为什么会出现这中情况呢?

    原来是线程非安全方式访问控件。就是说,如果创建某控件的线程之外的其他线程试图调用该控件,则调试器会引发一个 InvalidOperationException,并提示消息:“从不是创建控件 control name 的线程访问它。”

     

  • 那这种情况该如何处理呢?

    可以通过将 CheckForIllegalCrossThreadCalls 属性的值设置为 false 来禁用此异常。

    MSDN中提到了通过控件的 InvokeRequired 属性来判断调用控件的是哪一个线程,如果是非安全线程调用空间则使用实际调用空间的委托来调用Invoke。

    Invoke(Delegate, array< Object[]()>[] )         该方法的作用:在拥有此控件的基础窗口句柄的线程上执行指定的委托。

     

  • 我是这样做的

    1.查询控件的 InvokeRequired 属性。

    2.如果 InvokeRequired 返回true,则使用实际调用控件的委托来调用Invoke。

    3.如果 InvokeRequired 返回false,则直接调用控件。

    代码如下:

     

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Net.Sockets;
    using System.Net;
    using System.Threading;
    
    namespace _01_socketclient
    {
    	public partial class SocketClient : Form
    	{
    		Thread receiveThread = null;	//接受线程
    		delegate void SetTextCallback(string text);//invoke的方式实现安全调用
      
    		public SocketClient()
    		{
    			InitializeComponent();
    		}
    
    		private void btnConnection_Click(object sender, EventArgs e)
    		{
    			//实例接收线程
    			receiveThread = new Thread(new ThreadStart(RecevieThread));
    			//设置为后台线程
    			receiveThread.IsBackground = true;
    			//启动接受线程
    			receiveThread.Start();
    		}
    
    		/// <summary>
    		/// 显示文本信息
    		/// </summary>
    		/// <param name="msg"></param>
    		private void ShowMsg(string msg)
    

       {     if (txtShow.InvokeRequired)     {

         SetTextCallback d = new SetTextCallback(ShowMsg); ;      Invoke(d, new object[] { msg });     }     else     {      txtShow.AppendText(msg + "\r\n");     }    }

    /// <summary> /// 接收线程执行方法 /// </summary> private void RecevieThread() { string strMsg = "hello world" ShowMsg(strMsg); } } }

     

    -The End-

    © Jervis

     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值