0

我是多线程的新手。我在下面搜索了一些基本示例是代码

Imports System.Threading
Public Class Form1
Dim t As New Thread(AddressOf Me.BackgroundProcess)
Private Sub btnStartThread_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStartThread.Click
    t.Start()
End Sub

Private Sub StopButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StopButton.Click
    t.Abort()
End Sub

Public Sub BackgroundProcess()
    Dim i As Integer = 1

    If Me.InvokeRequired Then
        Me.Invoke(New MethodInvoker(AddressOf BackgroundProcess))
    Else
        Do While True
            Me.ListBox1.Items.Add("Iteration:" & i)
            i += 1
        Loop
    End If
End Sub
End Class

当我点击开始线程时,我的 UI 变得无响应。这背后的原因是什么。下面是 UI 的屏幕截图 表格1

4

3 回答 3

1

您在“后台”线程中的代码检查它是否在 UI 线程上

If Me.InvokeRequired Then

如果没有,它会告诉它在 UI 线程上运行。

Me.Invoke(New MethodInvoker(AddressOf BackgroundProcess))

如果它在 UI 线程上,它就处于一个循环中,阻塞 UI 线程,而不进行抽水。

Do While True

为了让它发挥作用,许多方法之一是这样的:

Public Delegate Sub AddItemDelegate(ByVal item As Object)
Public Sub BackgroundProcess()
    Dim i As Integer = 1

    Do While True
        i += 1
        If Me.InvokeRequired Then
            Me.Invoke(New AddItemDelegate(AddressOf AddItem), "Iteration:" & i)
         Else
            AddItem("Iteration:" & i)
        End If
    Loop
End Sub
Private Sub AddItem(ByVal item As Object)
    Me.ListBox1.Items.Add(item)
End Sub

使用委托是首选方式。

于 2013-09-24T13:52:01.257 回答
0

您基本上是在使用大量更新来处理 UI 线程,因此它永远没有机会响应用户输入。将循环更改为休眠一小段时间。

    Do While True
        Me.ListBox1.Items.Add("Iteration:" & i)
        i += 1
        Thread.Sleep(100)
    Loop
于 2013-09-24T13:53:00.827 回答
0

运行代码时,UI 没有响应,因为 UI 在很短的时间内接收到大量更新,要么停止循环无限:

        Do While True
            Me.ListBox1.Items.Add("Iteration:" & i)
            If i > 10 Then
                Exit Do
            End If
            i += 1
        Loop

或者在每个循环之后添加一个等待计时器以减慢 UI 更新的频率:

        Do While True
            Me.ListBox1.Items.Add("Iteration:" & i)
            i += 1
            'Sleep for 1 second
            Thread.CurrentThread.Sleep(1000)
        Loop

此外,您应该停止在 UI 线程上运行的代码,因为您当前正在创建一个线程,然后在 UI 线程上运行某些东西,这对我来说似乎不需要。

即改变

Me.InvokeRequired

成为

ListBox1.InvokeRequired

Me.Invoke(New MethodInvoker(AddressOf BackgroundProcess))

成为

ListBox1.Invoke(New MethodInvoker(AddressOf BackgroundProcess))
于 2013-09-24T14:03:21.053 回答