我有一个功能
public void ShowAllFly() { cbFly.Items.Clear(); cbFly.Items.Add("Uçuş Seçiniz..."); dsFlyTableAdapters.tblFlyTableAdapter _t=new KTHY.dsFlyTableAdapters.tblFlyTableAdapter(); dsFly _mds = new dsFly(); _mds.EnforceConstraints = false; dsFly.tblFlyDataTable _m = _mds.tblFly; _t.Fill(_m); foreach (DataRow _row in _m.Rows) { cbFly.Items.Add(_row["FlyID"].ToString()+"-"+_row["FlyName"].ToString() + "-" + _row["FlyDirection"].ToString() + "-" + _row["FlyDateTime"].ToString()); } _Thread.Abort(); timer1.Enabled = false; WaitPanel.Visible = false; }
在这样的Form_Load函数中;
{ _Thread = new System.Threading.Thread(new System.Threading.ThreadStart(ShowAllFly)); _Thread.Start(); _Thread.Priority = System.Threading.ThreadPriority.Normal; }
但是当我运行它时;
在ShowAllFly函数中
cbFly.Items.Clear(); ---- HERE Gives ERROR LIKE Control.Invoke must be used to interact with controls created on a separate thread.
问题是什么?
Windows窗体中有两个黄金线程规则:
为了与来自其他线程的UI进行交互,您需要使用委托并调用Control.Invoke/ 来“整理”对UI线程的调用BeginInvoke。您 可以 测试是否需要Invoke使用该InvokeRequired属性进行调用,但是这些天我个人还是倾向于这样做-不需要时调用没有太多的惩罚。
Control.Invoke
BeginInvoke
Invoke
InvokeRequired
C#3中的Lambda表达式(或C#2中的匿名方法)也使这更加令人愉悦。
例如,您可以使用:
cbFly.Invoke((MethodInvoker)(() => cbFly.Items.Clear()));
所有方括号都有点阻碍,因此,如果您使用的是C#3,则可能需要添加这样的扩展方法:
public static void Invoke(this Control control, MethodInvoker action) { control.Invoke(action); }
然后,您可以执行以下操作:
cbFly.Invoke(() => cbFly.Items.Clear());
这很简单。通常,您可以MethodInvoker通过捕获需要在委托中访问的任何变量来使用a 。
MethodInvoker
有关更多详细信息,请参见我的线程教程或Joe Albahari的。
作为第二件事,我看到您正在使用Thread.Abort-实际上是在您自己的线程上使用,尽管它之后还有其他调用。为什么?中止任何线程 其他 比你自己是一个“只有紧急”呼叫类型(这通常应遵循由应用正在反正卸载),我看不出有任何理由要中止当前线程时仍有待以后完成的工作。 ..
Thread.Abort