您的位置:首页 > 产品设计 > UI/UE

实现Winform 跨线程安全访问UI控件

2013-06-28 22:55 260 查看
在多线程操作WinForm窗体上的控件时,出现“线程间操作无效:从不是创建控件XXXX的线程访问它”,那是因为微软为了线程安全,窗体上的控件只能通过创建控件的线程来操作控件的数据,也就是只是是UI线程来操作窗体上的控件!
  要解决这个问题可以用以下方法:

1、关闭线程安全检查(不过本人不推荐,这种方式可能会发生一些不可预计的后果)

Control对象.CheckForIllegalCrossThreadCalls = false;

2、使用控件的Invoke方法(或BeginInvoke方法、BackgroundWorker) 

if (this.InvokeRequired)
{
this.Invoke(new Action(() => button1.Enabled = false));
//button1.Invoke(new MethodInvoker(delegate() { button1.Enabled = false; }));
//textBox1.SafeCall(() =>{ textBox1.Text = (i++).ToString();});

button1.Invoke(new MethodInvoker(() => button1.Enabled = false ));
button1.Invoke(new Action(() => button1.Enabled = false));  // 跨线程访问UI控件
}
else
{
button1.Enabled = false
}

3、使用委托

public delegate void AddLog(string info);
/// <summary>
/// 添加日志
/// </summary>
AddLog OnAddLog;

/// <summary>
/// 加载事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void FrmDataBackup_Load(object sender, EventArgs e)
{
OnAddLog = new AddLog(PrintMsg);
}

/// <summary>
/// 打印信息到即时显示控件
/// </summary>
/// <param name="info"></param>
public void PrintMsg(string info)
{
// InvokeRequired 属性判断是否跨线程操作
if (this.InvokeRequired)
{
this.Invoke(OnAddLog, info);
return;
}
listBoxInfo.Items.Insert(0, "[" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "] " + info);
if (listBoxInfo.Items.Count > 100)
{
listBoxInfo.Items.RemoveAt(100);
}
}


参考资料:http://www.cnblogs.com/easyfrog/archive/2012/02/08/2343075.html

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: