解法:
1.Form.CheckForIllegalCrossThreadCalls = False
2.建立委派
3.使用BackgroundWorker
首先在windows.form 的 onload事件建置一條執行緒
compareandprintout = new Thread(new ThreadStart(MRTcompareThread));
compareandprintout.Start();
這條thread 會執行compare()方法,存取UI控制項的程式就寫在裡面(存取textbox,combobox)
public void MRTcompareThread()
{
compare(); //裡面有無限迴圈
}
委派的建立!!
1.建立方法
publik int XXmethod(int a, int b);
2.宣告委派;委派參數,需要與被呼叫的方法一樣,包含回傳型別 (相同 signature)
private delegate void XXDelegate();
private delegate int XXDelegate(int a, int b);
3.引用委派(實體化),後指定方法
XXDelegate d = new XXDelegate(XXMethod); //參考的方法只要名稱就可以了
invoke();
真的開始囉~~
於class form1裡宣告委派
delegate void SetTextCallback(Control ctl,String str); 設置textbox.text
delegate string GetTextCallback(Control ctl); 讀取textbox.text
delegate string GetCBTextCallback(ComboBox ctl, int i); 讀取ComboBox
delegate string GetCBTextCallback(Listcontrol ctl, int i); 讀取ComboBox
另外要寫委派方法
public string gettext(Control ctl)
{
if (this.InvokeRequired) //InvokeRequired required compares the thread ID of the // calling thread to the thread ID of the creating thread. // If these threads are different, it returns true.
{
GetTextCallback d = new GetTextCallback(gettext);
// this.Invoke(d);
string x;
x =(string) this.Invoke(d, new Object[] { ctl });
return x;
}
else
{
return ctl.Text;
}
}
public void settext(Control ctl,String str)
{
if (this.InvokeRequired)
{
SetTextCallback s = new SetTextCallback(settext);
this.Invoke(s, ctl, str );
}
else
{
ctl.Text = str;
}
}
public string getCBtext(ComboBox ctl, int i)
{
if (this.InvokeRequired)
{
string try1 = ctl.GetItemText(i); //i = 1 2 3 4 遞增,奇怪~難道我誤會MSDN? 給出來的是combobox的item索引
string try2 = (string)ctl.Items[i];//
GetCBTextCallback Gcb = new GetCBTextCallback(getCBtext); //建立
string x;
x = (string)this.Invoke(Gcb, ctl, i);
return x;
}
else
{
return (string) ctl.Items[i];
// return ctl.GetItemText(i);
}
}
在非產生UI控制項的副執行緒主程式 compare裡面有
while(true)
{
for (i = 1; i < style="color: rgb(51, 204, 255);"> getCBtext(comboBox1,i) && startstation == true)
//if (nowBox.Text == comboBox1.Items[i].ToString() )
{
//onBox.Text = comboBox1.Items[i].ToString(); //debug會出錯(不同控制項執行緒叫用 ... 我忘了)
string y = getCBtext(comboBox1,i) ;
settext(onBox, y); //叫用方法,自動判斷叫用invoke
}
}
for (i = 1; i < style="color: rgb(255, 0, 0);">// if (onBox.Text == comboBox1.Items[i].ToString())
{
if (goal > getonposition)
{
//nexterrorstop = comboBox1.Items[i - 1].ToString();
nexterrorstop = getCBtext(comboBox1,i-1);
}
else
{
nexterrorstop = "error";
}
}
}
}
VB版
一樣 ,先建立一個拿來更新 UI 的方法( UpdateUI),再建立一個有相同 signature 的委派( UpdateUICallBack)
Private Delegate Sub UpdateUICallBack(ByVal newText As String, ByVal c As Control)
Private Sub UpdateUI(ByVal newText As String, ByVal c As Control)
If Me.InvokeRequired() Then
Dim cb As New UpdateUICallBack(AddressOf UpdateUI)
Me.Invoke(cb, newText, c)
Else
c.Text = newText
End If
End Sub
ref:
舊文重發:Windows 表單與多執行緒
HOW TO:進行對 Windows Form 控制項的安全執行緒呼叫
VB/ VBA/ C#/ Java/ C++ 語言學習筆記
沒有留言:
張貼留言
try comments