在多线程编程中,我们经常要在工作线程中去更新界面显示,而在多线程中直接调用界面控件的方法是错误的做法,Invoke 和 BeginInvoke 就是为了解决这个问题而出现的,使你在多线程中安全的更新界面显示。
正确的做法是将工作线程中涉及更新界面的代码封装为一个方法,通过 Invoke 或者 BeginInvoke 去调用,两者的区别就是一个导致工作线程等待,而另外一个则不会。
而所谓的“一面响应操作,一面添加节点”永远只能是相对的,使 UI 线程的负担不至于太大而已,因为界面的正确更新始终要通过 UI 线程去做,我们要做的事情是在工作线程中包揽大部分的运算,而将对纯粹的界面更新放到 UI 线程中去做,这样也就达到了减轻 UI 线程负担的目的了。
再举个简单例子说明下使用方法,比如你在启动一个线程,在线程的方法中想更新窗体中的一个TextBox..
using System.Threading;
public delegate void MyInvoke(string str);
private void btnStartThread_Click(object sender, EventArgs e)
{
Thread thread = new Thread(new ThreadStart(DoWord));
thread.Start();
}
public void DoWord()
{
MyInvoke mi = new MyInvoke(SetTxt);
BeginInvoke(mi,new object[]{"abc"});
}
public void SetTxt(string str)
{
txtReceive.Text += str + System.Environment.NewLine;
}
在项目中由于经常要调用WebService方法,但是每次调用比较复杂。所以就有了如下的代码
/// <summary> /// WS统一接口 /// </summary> /// <param name="sReqStr">校验字符串</param> /// <param name="clsName">调用类名</param> /// <param name="methodName">调用方法名</param> /// <param name="byteParam">参数</param> /// <param name="backParam">返回值(引用参数也以该形式返回)</param> /// 调用统一接口的方法要求:返回值为bool类型,DBHelper参数放在最后 /// <returns></returns> [WebMethod] public bool AllInOneWebService(string sReqStr, string clsName, string methodName, byte[] byteParam, ref byte[] backParam) { if (!Common.WebPassport.ChkReqStr(sReqStr)) throw new Exception("客户端版本或时间不正确"); object[] dicParam = null; if (byteParam != null) { dicParam = (object[])RemoteDS.SerializeZip.DecompressDecryptToObject(byteParam); } //添加参数DB object[] newParam = null; if (dicParam != null) { newParam = new object[dicParam.Length + 1]; for (int i = 0; i < dicParam.Length; i++) { newParam[i] = dicParam[i]; } newParam[dicParam.Length] = db; } else { newParam = new object[1]; newParam[0] = db; } //取得程序集 System.Reflection.Assembly assem = System.Reflection.Assembly.Load(clsName.Substring(0, clsName.IndexOf("."))); //取得方法信息 System.Reflection.MethodInfo m = assem.GetType(clsName).GetMethod(methodName); //调用方法 object ret = m.Invoke(assem.GetType(clsName), newParam); object obj = null; //区分WMS或者DAL调用 if (clsName.StartsWith("BLL_WMS")) { obj = BLL_WMS.BLL_Base.GetReturnValue(); } else { obj = DAL.DALBase.GetReturnValue(); } if (obj != null) { List<object> rtnValues = (List<object>)obj; //压缩返回参数 backParam = RemoteDS.SerializeZip.CompressEncryptToBytes(rtnValues); } //调用获取返回值方法 if (Convert.ToBoolean(ret)) { return true; } else { return false; } }