首页 > 解决方案 > 运行 backgroundworker VB.net 时写入 textbox.text

问题描述

嗨所以我有小表格申请

问题是当我在主线程上运行任务时,程序窗口没有响应

所以我的按钮将任务重定向到后台工作人员:

Private Sub btn_start_Click(sender As Object, e As EventArgs) Handles btn_start.Click

    BackgroundWorker1.RunWorkerAsync()

End Sub

现在我想在一个 Sub 中多次输出来自这个 Backgroudworker 的一些文本到我的文本框(txtlog)。我找到了一个允许这样做的解决方案。但是如果我必须多次使用它,这会使代码非常难看:

例子

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

        If txtLog.InvokeRequired Then
            txtLog.Invoke(Sub() txtLog.AppendText("My text" & vbNewLine))
            txtLog.Invoke(Sub() txtLog.ScrollToCaret())
        Else
            txtLog.AppendText("My text" & vbNewLine)
            txtLog.ScrollToCaret()
        End If

        Something in Backgroudworker . . .


        If txtLog.InvokeRequired Then
            txtLog.Invoke(Sub() txtLog.AppendText("My text" & vbNewLine))
            txtLog.Invoke(Sub() txtLog.ScrollToCaret())
        Else
            txtLog.AppendText("My text" & vbNewLine)
            txtLog.ScrollToCaret()
        End If
        

       . . . 

End Sub

有没有更短的方法可以让我在文本框中写字?

标签: vb.netvisual-studio-code

解决方案


使用 a 的全部意义BackgroundWorker在于您不必调用Invoke和使用委托。如果你无论如何都要这样做,那BackgroundWorker是没有意义的。

关于您拥有的代码,InvokeRequired当您知道DoWork事件处理程序将在后台线程上执行时,测试的意义何在?它总是会的TrueInvoke此外,当您可以调用一次并在一次调用中做尽可能多的事情时,为什么还要调用两次并增加所有开销?

Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    txtLog.Invoke(Sub()
                      txtLog.AppendText("My text" & vbNewLine))
                      txtLog.ScrollToCaret()
                  End Sub)

正如我所说,你根本不应该打电话Invoke。如果你想在 UI 线程上做一些事情,BackgroundWorker那么你调用ReportProgress并处理ProgressChanged事件。您要执行的代码进入事件处理程序,您可以ReportProgress根据需要调用。如果您需要传递数据,您可以使用第二个参数来传递数据,并从事件处理程序中ReportProgress取回数据。e.UserState这是我之前准备的一个:

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    'Raise the DoWork event in a worker thread.
    Me.BackgroundWorker1.RunWorkerAsync()
End Sub
 
'This method is executed in a worker thread.
Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, _
                                     ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    Dim worker As System.ComponentModel.BackgroundWorker = DirectCast(sender, System.ComponentModel.BackgroundWorker)
 
    For i As Integer = 1 To 100
        'Raise the ProgressChanged event in the UI thread.
        worker.ReportProgress(i, i & " iterations complete")
 
        'Perform some time-consuming operation here.
        Threading.Thread.Sleep(250)
    Next i
End Sub
 
'This method is executed in the UI thread.
Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As Object, _
                                              ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
    Me.ProgressBar1.Value = e.ProgressPercentage
    Me.Label1.Text = TryCast(e.UserState, String)
End Sub
 
'This method is executed in the UI thread.
Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, _
                                                 ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
    Me.Label1.Text = "Operation complete"
End Sub

推荐阅读