1、不使用委托:在构造函数或者窗体Load的代码里添加下面一句:
Control.CheckForIllegalCrossThreadCalls = false;
2、使用委托:
1- 创建线程:
Private Strt As System.Threading.Thread
2- 启动线程:
Strt = New System.Threading.Thread(AddressOf MyThread1)
Strt.Start()
3- Add the thread sub (MyThread1) and put whatever you want and remember that the lines which access a control from this thread will be separated to into another sub (the Delegate sub)
Sub MyThread1
' Working code
' Working code
' Working code
' Working code
' Working code
' Working code
AccessControl()
End Sub
From the previous code you will notice 2 things:
1st: AccessControl the sub which will be delegated.
2nd: ' Working code - which doesn't need a delegate to get it work. In other mean, it doesn't show up the error message you receive.
4- and finally, add the delegated sub:
Private Sub AccessControl()
If Me.InvokeRequired Then
Me.Invoke(New MethodInvoker(AddressOf AccessControl))
Else
' Code wasn't working in the threading sub
' Code wasn't working in the threading sub
' Code wasn't working in the threading sub
' Code wasn't working in the threading sub
' Code wasn't working in the threading sub
Button2.Visible = True
Button3.Visible = True
Opacity = 1
ShowInTaskbar = True
End If
End Sub
From the previous code you will notice that all the codes which wasn't working in the threading sub will be added after "Else" line.
examples for some codes which needs to be delegated:
(Control).Visible
Me.Opacity
Me.ShowInTaskbar
I hope i simplified it enough, and now no worry about this issue again.
补充: 在程序中加入Label.CheckForIllegalCrossThreadCalls = False 也可以解决"线程间操作无效: 从不是创建控件XXXXX的线程访问它",但此方法不推荐,强烈建议学习上文的Invoke方法解决。
另一种委托方法的实现
private delegate void TestDelegate();
private void DelegateMethod(){
label......
}
private void StartMethod(){
this.Invoke(new TestDelegate(DelegateMethod))
}
private button_click(...){
Thread thread = new Thread(new ThreadStart(StartMethod));
thread.Start();
}
public delegate void treeinvoke();
private void UpdateTreeView()
{
MessageBox.Show(Thread.CurrentThread.Name);
}
private void button1_Click(object sender, System.EventArgs e)
{
Thread.CurrentThread.Name = "UIThread";
Thread th = new Thread(new ThreadStart(StartThread));
th.Start();
}
private void StartThread()
{
Thread.CurrentThread.Name = "Work Thread";
treeView1.BeginInvoke(new treeinvoke(UpdateTreeView));
}