C#线程中调用主窗体控件处理方法

有时候我们需要在线程中打印消息到界面,但界面线程和运行线程之间不能跨线程操作,会报错误,解决方法如下,
1调用界面控件之前,检测当前线程是否和界面线程相同,
2如果不同,启用BeginInvoke委托调用方法解决异常

  #region 委托显示
        delegate void DisplayCallback(object displayer);
        public void ShowMsgCallback(object displayer)
        {
            // InvokeRequired required compares the thread ID of the 
            // calling thread to the thread ID of the creating thread. 
            // If these threads are different, it returns true. 

            int n = 0;
            Type type = displayer.GetType();
            dynamic obj = Convert.ChangeType(displayer, type);

            while (obj.IsHandleCreated == false)
            {
                //解决窗体关闭时出现“访问已释放句柄“的异常
                if (obj.Disposing || obj.IsDisposed)
                    return;
                Application.DoEvents();
                Thread.Sleep(1);
                if (n++ > 100) return;
            }
            //如果调用控件的线程和创建创建控件的线程不是同一个则为True
            if (obj.InvokeRequired)
            {
                DisplayCallback d = new DisplayCallback(ShowMsgCallback);
                obj.BeginInvoke(d, new object[] { displayer });
            }
            else
            {
                showmsg(obj);
            }
        }
        #endregion
        #region 显示到指定控件       
        public void showmsg(TextBox tb)
        {
            if (list_msgdat.Count == 0 || tb == null) return;

            while (list_msgdat.Count > 0)
            {
                MsgData msg = list_msgdat.First();
                if ((msg.msg_type & MsgCfg) != 0)
                {
                    tb.AppendText(msg.ToString() + "\r\n");
                }

                if (((int)msg.msg_type & ((int)MsgCfg) >> 8) != 0)
                {
                    SaveMsg(msg.ToString());
                }
                if (tb.Lines.Count() > MsgMaxLine / 2)
                {
                    List<string> str_list = tb.Lines.ToList();
                    str_list.RemoveAt(0);
                    tb.Lines = str_list.ToArray();
                }

                tb.SelectionStart = tb.Text.Length;
                tb.ScrollToCaret();

                lock (LockObj)
                {
                    list_msgdat.RemoveFirst();
                }
            }
        }
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值