为了线程的安全性和降低代码的依赖程度,C# windows编程中线程函数与调用的界面之间通信最好用委托来解决。
参数交互函数如下:
delegate void SetControlValueCallback(Control oControl, string propName, object propValue); //声明指向调用函数的委托 /// <summary> /// 线程调用的设置界面控件属性的函数 /// </summary> /// <param name="oControl">控件对象</param> /// <param name="propName">属性名称</param> /// <param name="propValue">属性值</param> private void SetControlPropertyValue(Control oControl, string propName, object propValue) { if (oControl.InvokeRequired) { SetControlValueCallback d = new SetControlValueCallback(SetControlPropertyValue); oControl.Invoke(d, new object[] { oControl, propName, propValue }); } else { Type t = oControl.GetType(); System.Reflection.PropertyInfo[] props = t.GetProperties(); foreach (System.Reflection.PropertyInfo p in props) { if (p.Name.ToUpper() == propName.ToUpper()) { p.SetValue(oControl, propValue, null); } } } }
使用方法:
如启动如下线程:
Thread t = new Thread(new ThreadStart(LoadData)); t.Start();
线程函数如下:
/// <summary> /// Load all data from database /// </summary> void LoadData() { string SqlStr = "SELECT * FROM ExtensionPhone ORDER BY Department,Division"; DataSet ds = this.GetDataSet(SqlStr); if (ds == null) return; dt = ds.Tables[0]; //在线程中直接用下面的两行会出现错误 //grd.DataSource = dt; //lbTotal.Text = "Total Records: " + dt.Rows.Count.ToString(); //用委托的函数代替设置属性和传递参数 SetControlPropertyValue(grd, "DataSource", dt); SetControlPropertyValue(txtSearch, "Focus", null); SetControlPropertyValue(lbTotal, "Text", "Total Records: " + dt.Rows.Count.ToString()); }
线程执行结果如下图: