//注意:耗时的代码不能放在 this.BeginInvoke(new MethodInvoker(() => 耗时代码 })); //中执行;否则没有产生异步的效果。
//BeginInvoke中只能放置操作控件的代码。BeginInvoke将子线程线程通过委托抛向UI主线程 。
Thread thread = new Thread(() =>{if (this.IsHandleCreated)this.BeginInvoke(new MethodInvoker(() =>{this.txtRFID.Enabled = false;}));int iRet = -1;string strTid = "";iRet = WriteCardHelper.Instance.ReadTID(ref strTid); //读取耗时的代码;//注意:耗时的代码不能放在 this.BeginInvoke(new MethodInvoker(() => 耗时代码 })); //中执行;否则没有产生异步的效果。//BeginInvoke中只能放置操作控件的代码。BeginInvoke将子线程线程通过委托抛向UI主线程 。if (this.IsHandleCreated)this.BeginInvoke(new MethodInvoker(() =>{this.errorProvider.SetError(this.txtRFID, "");if (0 == iRet){WriteCardHelper.Instance.SetAlarm();this.txtRFID.Text = strTid;this.txtRFID.BackColor = Color.White;this.errorProvider.SetError(this.txtRFID, "");}else{this.txtRFID.Text = "";this.txtRFID.BackColor = Color.Pink;}this.txtGasBottleNo.Focus();this.txtRFID.Enabled = true;}));});thread.IsBackground = true;thread.Start();
另一种做法:
th = new Thread(delegate (){//3就是要循环轮数了for (int i = 0; i < ListImages.Count; i++){//调用方法//设置图片的位置和显示时间(1000 为1秒)ChangeImage(ListImages[i], 3000);}BandData();});th.IsBackground = true;th.Start();
另外 关于异步执行的方式为 :
{this.Invoke(new Action(() => {//写入相对比较耗时的操作})); }
同上有类似如此写法
Invoke((new Action(() =>{MainContent.AppendText($"{DateTime.Now} 接收到主题为 {e.Topic},内容是:{1232312313} \n\r");})));
如果数据参数内存在错误为:
在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke 解决办法
if (this.IsHandleCreated){this.Invoke(new EventHandler(delegate{......}));}
以下显示为多线程通过委托来修改 UI控件上的值。
delegate void setCtrlTextHandle(Control ctrl, string txt);void setCtrlText(Control ctrl, string txt){if (this.InvokeRequired){MethodInvoker invoker = new MethodInvoker(delegate(){setCtrlTextMethod(ctrl, txt);});this.BeginInvoke(invoker, ctrl, txt);}else{setCtrlTextMethod(ctrl, txt);}}void setCtrlTextMethod(Control ctrl, string txt){ctrl.Text = txt;}
另一种做法是:
```csharpdelegate void SetBindList(List<Msg> List); //定义委托public void SetDGVList(List<Msg> List){if (DGV.InvokeRequired) //控件是否跨线程?如果是,则执行括号里代码{SetBindList setListCallback = new SetBindList(SetDGVList); //实例化委托对象DGV.Invoke(setListCallback, List); //重新调用SetListBox函数(传入参数list)以主线程同步的模式进入操作}else //否则,即是本线程的控件,控件直接操作{DGV.DataSource = List;}}