vb.net - 尝试更新线程内的GUI(从BackgroundWorker开始)

标签 vb.net multithreading

我在使用不同线程上的GUI更新时遇到问题。我的情况是这样的:

我有一个带有单个复选框的主窗体。在Form_Load事件中,我启动了一个后台工作器。在BackgroundWorker_DoWork事件中,我调用了一个新类,该类又启动了一个新线程。从这个线程,我试图在Form1上设置复选框的Checked状态,但是没有任何运气。

到目前为止,我有以下代码示例:

Public Class Form1
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Try
            BackgroundWorker1.RunWorkerAsync()

        Catch ex As Exception
            MsgBox(ex.ToString)
        End Try
    End Sub

    Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
        Try

            Do While Not BackgroundWorker1.CancellationPending = True
                Dim cl As New HandleClient
                Me.Invoke(Sub() Checkbox1.Checked = True)
            Loop

        Catch ex As Exception
            MsgBox(ex.ToString)
        End Try
    End Sub
End Class

Public Class HandleClient

    Public Sub startClient()
        Dim ctThread As Threading.Thread = New Threading.Thread(AddressOf start)
        ctThread.Start()
    End Sub

    Private Sub start()
        While (True)
            Try
                ...
                ..

            Catch ex As Exception
                    Form1.Invoke(Sub() Form1.Checkbox1.Checked = False) '<== Fails here
            End Try
        End While
    End Sub
End Class

我尝试使用ThreadSafe调用并通过单独的类设置属性,但是我收到一条错误消息,指出我无法使用BeginInvoke或Checkbox只是不更新​​(没有错误)。

任何帮助表示感谢。

最佳答案

我不确定为什么要从已经为该工作程序启动新线程的后台工作程序启动新线程。好像是多余的线程。 backgroundworker工作线程无法更新UI线程所拥有的控件,这与新句柄客户端线程也无法更新的原因相同。使用后台对象,您可以通过引发后台工作程序的ProgressChanged事件来更新UI线程,并将更新代码放入处理该事件的方法中。

Public Class Form1
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Try
            BackgroundWorker1.WorkerReportsProgress = true
            BackgroundWorker1.RunWorkerAsync()

        Catch ex As Exception
            MsgBox(ex.ToString)
        End Try
    End Sub

    Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork

        Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)

        Try

            Do While Not worker.CancellationPending = True
                ' Do the thing that is in the Try block of the HandleClient
                Try
                    ' ...
                    ' ..
                    ' Using a value of 1 for true, since you used False in the catch statement
                    worker.ReportProgress(1)
                    ' Or you can use the overloaded method
                    worker.ReportProgress(0, True)
                Catch ex As Exception
                    ' Form1.Invoke(Sub() Form1.Checkbox1.Checked = False) '<== Fails here
                    ' Using a value of 0 for false
                    worker.ReportProgress(0)
                    ' Or you can use the overloaded method
                    worker.ReportProgress(0, False)
                End Try

            Loop

        Catch ex As Exception
            MsgBox(ex.ToString)
        End Try
    End Sub

    Private Sub backgroundWorker1_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs) Handles backgroundWorker1.ProgressChanged
        ' If you used the overloaded method, you can delete this case statement
        Select Case e.ProgressPercentage
            Case 0
                Form1.Checkbox1.Checked = True
            Case 1
                Form1.Checkbox1.Checked = False
            Case Else 
                Form1.Checkbox1.CheckState = CheckState.Indeterminate
        End Select

        ' Or just use the userstate as mention in the comments
        Form1.Checkbox1.Checked = DirectCast(e.UserSate, Boolean)

    End Sub 

End Class

关于vb.net - 尝试更新线程内的GUI(从BackgroundWorker开始),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29009962/

相关文章:

c - 使用 C DLL 的 VB.Net

java - 循环中的 CompletableFuture : How to collect all responses and handle errors

java - Java API调用将根据队列大小进行合并,或者在最早的项目插入队列后的4秒内执行

mysql - 从一个表中提取记录并将其存储在另一张表中并包含附加数据

java - Java 中的多线程死锁

c - 为什么 Helgrind 显示 "lock order violated"错误消息?

android - 订阅者的 onNext() 方法在哪个线程上运行?

vb.net - 可能的设计模式建议?

mysql - 标准 SQL SELECT * FROM TABLE 返回语法错误

c# - 将字符串转换为 TitleCase、SentenceCase、UpperCase 和 LowerCase,但如果单词在 "quotation marks"内则忽略大小写