vb.net - 后台线程问题

发布于 2024-12-08 16:37:36 字数 673 浏览 0 评论 0原文

由于某种原因,我的应用程序中的后台线程无法更改主窗体上的任何标签、文本框值等。没有编译错误,当线程执行时什么也没有发生。

这是一些示例代码:

Imports System.Threading

Public Class Class1
    Dim tmpThread As System.Threading.Thread

    Private Sub bgFindThread()
        Form1.lblStatus.Text = "test"
    End Sub

    Public Sub ThreadAction(ByVal Action As String)
        If Action = "Start" Then
            tmpThread = New System.Threading.Thread(New System.Threading.ThreadStart(AddressOf bgFindThread))
            tmpThread.Start()
        ElseIf Action = "Abort" Then
            If tmpThread.IsAlive = True Then tmpThread.Abort()
        End If
    End Sub

End Class

有人可以让我知道我做错了什么吗?

For some reason a background thread in my app can't change any labels, textbox values, etc on my main form. There is no compile errors, when the thread executes nothing happens.

Here is some example code:

Imports System.Threading

Public Class Class1
    Dim tmpThread As System.Threading.Thread

    Private Sub bgFindThread()
        Form1.lblStatus.Text = "test"
    End Sub

    Public Sub ThreadAction(ByVal Action As String)
        If Action = "Start" Then
            tmpThread = New System.Threading.Thread(New System.Threading.ThreadStart(AddressOf bgFindThread))
            tmpThread.Start()
        ElseIf Action = "Abort" Then
            If tmpThread.IsAlive = True Then tmpThread.Abort()
        End If
    End Sub

End Class

Can someone let me know what I'm doing wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

ゝ偶尔ゞ 2024-12-15 16:37:37

AFAIK 上面的代码会抛出异常 IllegalCrossThreadException,这是因为后台线程与 UI 线程不同,并且后台尝试在其他线程上设置值。所以Windows窗体检查每个正常工作的线程。
您可以将 Control.CheckForIllegalCrossThreadCalls 设置为 false 以使其正常工作。

下面的代码是当设置属性未运行时

Add into your code
------------------------------
Delegate Sub MyDelegate()
Private Sub RunMyControl()
  lblStatus.Text = "test"
End Sub

Change your code
------------------------------
Private Sub bgFindThread
  lblStatus.BeginInvoke (New MyDelegate(AddressOf RunMyControl))
End Sub

该方法异步地将代码从后台线程运行到UI线程。

AFAIK code above will throw an exception IllegalCrossThreadException, it is because the background thread is not the same as UI thread and background try to set value on other thread. So windows form check every thread that work properly.
You can set Control.CheckForIllegalCrossThreadCalls to false to make it works.

Code below is when setting property is not run

Add into your code
------------------------------
Delegate Sub MyDelegate()
Private Sub RunMyControl()
  lblStatus.Text = "test"
End Sub

Change your code
------------------------------
Private Sub bgFindThread
  lblStatus.BeginInvoke (New MyDelegate(AddressOf RunMyControl))
End Sub

The method asyncronsly run code from background thread to UI thread.

一袭白衣梦中忆 2024-12-15 16:37:37

您只能从 UI 线程访问 UI 控件。

我建议先阅读此内容: http://www.albahari.com/threading/

You can only access UI controls from the UI thread.

I suggest reading this first: http://www.albahari.com/threading/

夜血缘 2024-12-15 16:37:37

正如其他人提到的,禁止(出于充分的理由)从非 UI 线程更新 UI 元素。

规范的解决方案如下:

  • 测试您是否在 UI 线程外部
  • 如果是,则请求在 UI 线程内部执行操作
  • [UI 线程内部] 更新控件。

在您的情况下:

Private Sub bgFindThread()
    If lblStatus.InvokeRequired Then
        lblStatus.Invoke(New Action(AddressOf bgFindThread))
        Return
    End If

    lblStatus.Text = "test"
End Sub

唯一改变的是方法开头的保护子句,它测试我们是否在 UI 线程内,如果不在,则请求在 UI 线程中执行并返回。

As others have mentioned, it is forbidden (for good reasons) to update UI elements from a non-UI thread.

The canonical solution is as follows:

  • Test whether you are outside the UI thread
  • If so, request for an operation to be performed inside the UI thread
  • [Inside the UI thread] Update the control.

In your case:

Private Sub bgFindThread()
    If lblStatus.InvokeRequired Then
        lblStatus.Invoke(New Action(AddressOf bgFindThread))
        Return
    End If

    lblStatus.Text = "test"
End Sub

The only thing that changed is the guard clause at the beginning of the method which test whether we’re inside the UI thread and, if not, requests an execution in the UI thread and returns.

冷情 2024-12-15 16:37:37

您可以使用委托来更新后台线程中的 UI 控件。

例子

Private Delegate Sub bkgChangeControl(ByVal bSucceed As Boolean)
Private dlgChangeControl As bkgChangeControl = AddressOf ChangeControl

Private Sub threadWorker_ChangeControl(ByVal bSucceed As Boolean)
    Me.Invoke(dlgChangeControl, New Object() {bSucceed})
End Sub  
     Private Sub ChangeControl()
     Me.lable="Changed"
     End Sub
      'In your background thread, call threadWorker_ChangeControl.

You can use a delegate to update UI controls in a background thread.

Example

Private Delegate Sub bkgChangeControl(ByVal bSucceed As Boolean)
Private dlgChangeControl As bkgChangeControl = AddressOf ChangeControl

Private Sub threadWorker_ChangeControl(ByVal bSucceed As Boolean)
    Me.Invoke(dlgChangeControl, New Object() {bSucceed})
End Sub  
     Private Sub ChangeControl()
     Me.lable="Changed"
     End Sub
      'In your background thread, call threadWorker_ChangeControl.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文