簡體   English   中英

無法更新文本框vb.net -crossthreading

[英]Cannot update textbox vb.net -crossthreading

我正在嘗試使一個應用程序運行多個(特別是adb)命令並獲取輸出並顯示在標簽中。

首先,我需要開始執行命令的過程。 感謝stackoverflow和@pasty,我找到了這個(第二個答復): 如何在Visual Basic中逐行獲取命令提示符窗口的輸出?

好吧,我認為由於將其輸出到控制台,因此只需將其寫入標簽即可。 大錯! 它給了我一個交叉線程錯誤! 有點谷歌搜索和堆棧溢出,我發現了這一點: vb.net是從不是在其上創建的線程的線程訪問的

好吧,我試圖實現這一點,但是程序崩潰了

這是代碼:

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    ' store error output lines

    Dim executable As String() = {"adb", "adb"}
    Dim arguments As String() = {"help", "reboot"}
    For i As Integer = 0 To 0
        Dim process = New Process()
        process.StartInfo = createStartInfo(executable(i), arguments(i))
        process.EnableRaisingEvents = True
        AddHandler process.Exited, Sub(ByVal sendera As Object, ByVal ea As System.EventArgs)
                                       Console.WriteLine(process.ExitTime)
                                       Console.WriteLine(". Processing done.")
                                       'UpdateTextBox(ea)

                                   End Sub
        ' catch standard output
        AddHandler process.OutputDataReceived, Sub(ByVal senderb As Object, ByVal eb As DataReceivedEventArgs)
                                                   If (Not String.IsNullOrEmpty(eb.Data)) Then
                                                       Console.WriteLine(String.Format("{0}> {1}", DateTime.Now.ToString("dd.MM.yyyy HH:mm:ss"), eb.Data))
                                                       'UpdateTextBox(eb.Data)

                                                   End If
                                               End Sub
        ' catch errors
        AddHandler process.ErrorDataReceived, Sub(ByVal senderc As Object, ByVal ec As DataReceivedEventArgs)
                                                  Console.WriteLine(String.Format("! {0}", ec.Data))
                                                  Dim a As String = String.Format("! {0}", ec.Data)
                                                  'UpdateTextBox(a)
                                              End Sub
        ' start process
        Dim result = process.Start()
        ' and wait for output
        process.BeginOutputReadLine()
        ' and wait for errors :-)
        process.BeginErrorReadLine()
        process.WaitForExit()

    Next

End Sub

Private Sub UpdateTextBox(ByVal a As String)
    If Me.InvokeRequired Then
        Dim args() As String = {a}
        Me.Invoke(New Action(Of String)(AddressOf UpdateTextBox), args)
        Return
    End If
    Label1.Text += "a"
End Sub

Private Function createStartInfo(ByVal executable As String, ByVal arguments As String) As ProcessStartInfo
    Dim processStartInfo = New ProcessStartInfo(executable, arguments)
    processStartInfo.WorkingDirectory = Path.GetDirectoryName(executable)
    ' we want to read standard output
    processStartInfo.RedirectStandardOutput = True
    ' we want to read the standard error
    processStartInfo.RedirectStandardError = True
    processStartInfo.UseShellExecute = False
    processStartInfo.ErrorDialog = False
    processStartInfo.CreateNoWindow = True
    Return processStartInfo

End Function

以及源代碼: https : //github.com/iAmAOpenSource/SyncfusionWindowsFormsApplication3

process.WaitForExit()的調用將阻塞UI線程,直到生成的進程退出為止,但是在處理process.OutputDataReceived事件中的process.OutputDataReceived中,您正在調用Me.Invoke ,它試圖在被阻塞的UI線程上運行代碼,因此程序凍結。 您可以將Button1_Click的邏輯移到另一個線程上,例如

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Task.Run(
        Sub()
            ... current logic
        End Sub
    )
End Sub

這樣,UI線程將不會被阻塞,並且Me.Invoke調用不會導致死鎖。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM