atr*_*ame 10 c# multithreading
我有一个功能
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;
}
Run Code Online (Sandbox Code Playgroud)
在Form_Load函数中像这样;
{
_Thread = new System.Threading.Thread(new System.Threading.ThreadStart(ShowAllFly));
_Thread.Start();
_Thread.Priority = System.Threading.ThreadPriority.Normal;
}
Run Code Online (Sandbox Code Playgroud)
但是当我跑的时候;
在ShowAllFly函数中
cbFly.Items.Clear(); ---- HERE Gives ERROR LIKE Control.Invoke must be used to interact with controls created on a separate thread.
Run Code Online (Sandbox Code Playgroud)
问题是什么?
Jon*_*eet 50
Windows窗体中有两个主要的线程规则:
为了从不同的线程与UI进行交互,您需要使用委托并调用Control.Invoke/ 来"调整"对UI线程的调用BeginInvoke.你可以测试你是否需要Invoke使用该InvokeRequired属性进行调用,但是这些天我个人倾向于只是这样做 - 当你不需要时调用没有太多的惩罚.
C#3中的Lambda表达式(或C#2中的匿名方法)也使这更令人愉快.
例如,您可以使用:
cbFly.Invoke((MethodInvoker)(() => cbFly.Items.Clear()));
Run Code Online (Sandbox Code Playgroud)
所有括号都会受到影响,所以如果你使用C#3,你可能想要添加这样的扩展方法:
public static void Invoke(this Control control, MethodInvoker action)
{
control.Invoke(action);
}
Run Code Online (Sandbox Code Playgroud)
然后你可以这样做:
cbFly.Invoke(() => cbFly.Items.Clear());
Run Code Online (Sandbox Code Playgroud)
这简单易行.通常,您可以MethodInvoker通过捕获代理中需要访问的任何变量来逃避使用.
有关详细信息,请参阅我的线程教程或Joe Albahari's.
作为次要问题,我看到你正在使用Thread.Abort- 实际上是在你自己的线程上,尽管它之后还有其他的调用.为什么?中止任何线程其他比你自己是一个"只有紧急"呼叫类型(这通常应遵循由应用正在反正卸载),我看不出有任何理由中止当前线程时,有仍有许多工作之后进行. ..
需要调用另一个(ui)线程中控件的交互,如下所示:
Run Code Online (Sandbox Code Playgroud)public delegate void ProcessResultDelegate(string result); void ProcessResult(string result) { if (textBox1.InvokeRequired) { var d = new ProcessResultDelegate(ProcessResult); d.Invoke(result); } else { textBox1.Text = result; } }