C#中多线程里面如何调用控件

来源:互联网 发布:电视直播软件电脑版 编辑:程序博客网 时间:2024/06/05 08:47
  1. 首先我们在C#中的Winform中经常会遇到多线程的情况,这个时候如果我要对界面进行同步更新,直接在多线程里面调用控件是会报如下的错误: InvaidOperationException,无效的操作异常。
  2. 我们从异常中可以读取到:线程间操作无效,从不是创建的控件的线程去访问它。
  3. 在clickBtn的点击事件里创建的线程,不能直接调用DoButton方法去操作clickBtn的文本
private void clickBtn_Click(object sender,EventArgs e){//在clickBtn的点击事件里面创建一个线程Thread thread = new Thread(new ThreadStart(DoButton));thread.Start();}public void DoButton(){  clickBtn.Text ="改变点击";}

这里写图片描述

4.对于涉及到线程的问题,我们如何去处理此类问题,通常有两种
方法来处理这样的问题:
①通过设置Control的属性;
②利用事件委托delegate来处理->1是通过常用方法,2是匿名方法;
Control属性的设置一般是在Form_Load()的方法中,设置

//设置为false,表示对错误的线程调用不进行报错Control.CheckForIllegalCrossThreadCalls = false; 

Delegate事件委托进行处理:
普通方法:

//声明一个事件委托public delegate void SetButtonTextEvent(string strMsg);public void SetButtonText(string strMsg){    if( btnClick.InvokeRequired)    {        SetButtonTextEvent sBTEvent = new SetButtonTextEvent(SetButtonText);    SetButtonText.Invoke(sBTEvent,new Object[]{strMsg});    }    else    {    //这边一定要加要处理的控件属性        btnClick.Text =strMsg;     }}//定义一个调用这个函数的线程方法public void DoSetText(){    SetButtonText("yyyy");}//在线程里面调用的时候Thread thread = new Thread(new ThreadStart(DoSetText));thread.Start();

匿名方法:

public void SetButtonText(string strMsg){    SetButtonTextEvent sBTEvent = delegate(string str )    {        btnClick.Text = str;    }    btnClick.Invoke(sBTEvent,new object[]{strMsg});}

当然现在C#3.0以后可以Lambda表达式,所以我们可以更加简洁的方式写匿名委托;.NET Framework 3.5及其以后版本可以用Action封装方法:http://www.cnblogs.com/edisonchou/p/4104612.html
Lambda表达式: 这里写代码片()=>{} //语句Lambda
例如以下写法可以看上去非常简洁:

public void SetButtonText(string strMsg){    this.Invoke(new Action(()=>    {        btnClick.Text = strMsg;    }));}