BackgroundWorker 更改标签多线程VB.NET
BackgroundWorker change label multithread VB.NET
我是多线程和后台工作者的新手。
我试图根据教程和论坛主题编写一个简单的测试,但它没有按我预期的那样工作。
我有一个带有 Button1
、Label1
、BackgroundWorker1
控件的 windows 表单应用程序。
我想在单击按钮时执行此操作:
- 后台工作人员不断检查变量
state
True 或 False
- 首先将标签文本更改为 False(第一次状态 = false)
- 如果
state
在主线程中设置为True,将标签文本更改为True(state
在"Sample process"(For Next)结束时设置为True)
我的代码是:
Public state As Boolean
Public Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Debug.Print("Button1_Click ThreadID - " & Thread.CurrentThread.ManagedThreadId)
state = False
BackgroundWorker1.RunWorkerAsync()
'--Sample process in the main thread
For c = 0 To 10000
Debug.Print(c)
Next
state = True
End Sub
Dim c As Integer
Public Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
setlabel(state.ToString)
Do While state = False
Debug.Print("BackgroundWorker1_DoWork ThreadID - " & Thread.CurrentThread.ManagedThreadId & " - state: " & state)
Thread.Sleep(100)
Loop
setlabel(state.ToString)
End Sub
Public Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
Debug.Print("BackgroundWorker1_RunWorkerCompleted - State: " & state)
End Sub
Sub setlabel(text As String)
Label1.Invoke(Sub()
Label1.Text = text
End Sub)
End Sub
我的问题是:
- 标签的文本在开始时没有更改为 False
BackgroundWorker1_DoWork
- 在
Do While
中没有Debug.Print
输出为:
Button1_Click ThreadID - 9
0
1
2
...
9998
9999
10000
BackgroundWorker1_RunWorkerCompleted - State: True
我做错了什么?
您正在使用 For
循环占用 UI 线程:
For c = 0 To 10000
Debug.Print(c)
Next
您需要让 UI 线程空闲以便调用 setlabel(state.ToString)
以实际更新 UI。
所以你需要有一个类似计时器的东西(或者甚至是第二个后台工作者)在设置之前等待一段时间 state = True
。
我是多线程和后台工作者的新手。 我试图根据教程和论坛主题编写一个简单的测试,但它没有按我预期的那样工作。
我有一个带有 Button1
、Label1
、BackgroundWorker1
控件的 windows 表单应用程序。
我想在单击按钮时执行此操作:
- 后台工作人员不断检查变量
state
True 或 False - 首先将标签文本更改为 False(第一次状态 = false)
- 如果
state
在主线程中设置为True,将标签文本更改为True(state
在"Sample process"(For Next)结束时设置为True)
我的代码是:
Public state As Boolean
Public Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Debug.Print("Button1_Click ThreadID - " & Thread.CurrentThread.ManagedThreadId)
state = False
BackgroundWorker1.RunWorkerAsync()
'--Sample process in the main thread
For c = 0 To 10000
Debug.Print(c)
Next
state = True
End Sub
Dim c As Integer
Public Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
setlabel(state.ToString)
Do While state = False
Debug.Print("BackgroundWorker1_DoWork ThreadID - " & Thread.CurrentThread.ManagedThreadId & " - state: " & state)
Thread.Sleep(100)
Loop
setlabel(state.ToString)
End Sub
Public Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
Debug.Print("BackgroundWorker1_RunWorkerCompleted - State: " & state)
End Sub
Sub setlabel(text As String)
Label1.Invoke(Sub()
Label1.Text = text
End Sub)
End Sub
我的问题是:
- 标签的文本在开始时没有更改为 False
BackgroundWorker1_DoWork
- 在
Do While
中没有Debug.Print
输出为:
Button1_Click ThreadID - 9 0 1 2 ... 9998 9999 10000 BackgroundWorker1_RunWorkerCompleted - State: True
我做错了什么?
您正在使用 For
循环占用 UI 线程:
For c = 0 To 10000
Debug.Print(c)
Next
您需要让 UI 线程空闲以便调用 setlabel(state.ToString)
以实际更新 UI。
所以你需要有一个类似计时器的东西(或者甚至是第二个后台工作者)在设置之前等待一段时间 state = True
。