首页 > 代码库 > Winfrom 跨线程更新控件

Winfrom 跨线程更新控件

来源: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#?