VB.NET 线程间操作无效错误的解决办法

来源:互联网 发布:淘宝30元保证金怎么交 编辑:程序博客网 时间:2024/04/29 17:43
 
来自互联网,学习交流用。感谢作者。

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));
}