码迷,mamicode.com
首页 > 编程语言 > 详细

Winfrom 跨线程更新控件

时间:2014-08-12 18:53:54      阅读:276      评论:0      收藏:0      [点我收藏+]

标签:blog   http   color   io   for   ar   art   问题   

来源:http://www.cnblogs.com/rainbowzc/archive/2010/09/29/1838788.html

由于多线程可能导致对控件访问的不一致,导致出现问题。C#中默认是要线程安全的,即在访问控件时需要首先判断是否跨线程,如果是跨线程的直接访问,在运行时会抛出异常。

解决办法有两个:

1、不进行线程安全的检查

2、通过委托的方式,在控件的线程上执行

 

常用写法:(不安全)

 private void WriteToolStripMsg(string msg, Color color)
        {
            if (this.InvokeRequired)
            {
                this.BeginInvoke(new MethodInvoker(delegate()
                {
                    toolStripMsg.Text = msg;
                    toolStripMsg.ForeColor = color;

                }));
            }
            else
            {
                toolStripMsg.Text = msg;
                toolStripMsg.ForeColor = color;
            }
        }

private void btnLogin_Click(object sender, EventArgs e)
        {

            string userName = this.txtUserName.Text.Trim();
            string pwd = this.txtPwd.Text.Trim();

            if (userName.IsNullOrEmpty())
            {
                WriteToolStripMsg("请输入登录名...", Color.Red);
                this.txtUserName.Focus();
                return;
            }
            if (pwd.IsNullOrEmpty())
            {
                WriteToolStripMsg("请输入密码...", Color.Red);
                this.txtPwd.Focus();
                return;
            }

            if (userName.IsNotEmpty() && pwd.IsNotEmpty())
            {
                WriteToolStripMsg("系统正在登陆中...", Color.Blue);
                this.btnLogin.BtnEnabled = false;
                string msg = string.Empty;
                Thread t = new Thread(() =>
                {
                    //判断用户登录是否成功。
                    string restulMsg = string.Empty;
                    restulMsg = DataCenterService.Instance.Login(userName, pwd);
                    if (restulMsg.IsNullOrEmpty())
                    {
                        SysUser.CurrUserEntity = DataCenterService.Instance.GetInfoForName(userName);
                        this.DialogResult = DialogResult.OK;
                    }
                    else
                    {
                        WriteToolStripMsg(restulMsg, Color.Red);
                        this.BeginInvoke(new MethodInvoker(delegate()
                        {
                            this.btnLogin.BtnEnabled = true;
                        }));
                    }
                });
                t.IsBackground = true;
                t.Start();
            }
        }

  

上述写法并不是最安全的,存在一定的问题。

推荐写法:

        delegate void UpdateShowInfoDelegate(System.Windows.Forms.TextBox txtInfo, string Info);

        /// <summary>
        /// 显示信息
        /// </summary>
        /// <param name="txtInfo"></param>
        /// <param name="Info"></param>
        public void ShowInfo(System.Windows.Forms.TextBox txtInfo, string Info)
        {
            if (this.InvokeRequired)
            {
                //this.BeginInvoke(new MethodInvoker(delegate()
                //{
                //    txtInfo.AppendText(Info);
                //    txtInfo.AppendText(Environment.NewLine + "\r\n");
                //    txtInfo.ScrollToCaret();
                //}));
                Invoke(new UpdateShowInfoDelegate(ShowInfo), txtInfo,Info);
                return;
            }
            else
            {
                txtInfo.AppendText(Info);
                txtInfo.AppendText(Environment.NewLine + "\r\n");
                txtInfo.ScrollToCaret();
            }
        }

  

本文转载:http://stackoverflow.com/questions/661561/how-to-update-the-gui-from-another-thread-in-c

How to update the GUI from another thread in C#?

 

Winfrom 跨线程更新控件,布布扣,bubuko.com

Winfrom 跨线程更新控件

标签:blog   http   color   io   for   ar   art   问题   

原文地址:http://www.cnblogs.com/zfanlong1314/p/3907863.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!