//注意:耗时的代码不能放在 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;
}
另一种做法是:
```csharp
delegate 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;
}
}