使用事件从后台工作人员更新 UI 与另一个 class
Using Events to update UI from a backgroundworker with another class
我正在尝试使用事件从另一个 class 的后台工作者更新文本框。
这与 this SO post 中提到的问题相同,只是我使用的是 VB.NET。我正在尝试通过 @sa_ddam213.
实施第二个建议的解决方案
我收到一个错误:“跨线程操作无效:控制 'txtResult' 从创建它的线程以外的线程访问。”
这是我的代码:
Public Class DataProcessor
Public Delegate Sub ProgressUpdate(ByVal value As String)
Public Event OnProgressUpdate As ProgressUpdate
Private Sub PushStatusToUser(ByVal status As String)
RaiseEvent OnProgressUpdate(status)
End Sub
Public Sub ProcessAllFiles(ByVal userData As UserData)
'Do the work
End Sub
End Class
Public Class MainForm
Private bw As New BackgroundWorker
Private dp As New DataProcessor
Private Sub bw_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)
Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)
If bw.CancellationPending = True Then
e.Cancel = True
Else
dp.ProcessAllFiles(CType(e.Argument, UserData))
End If
End Sub
Private Sub dp_OnProgressUpdate(ByVal status As String)
txtResult.Text = status
End Sub
Private Sub MainForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
bw.WorkerReportsProgress = True
bw.WorkerSupportsCancellation = True
AddHandler bw.DoWork, AddressOf bw_DoWork
AddHandler bw.ProgressChanged, AddressOf bw_ProgressChanged
AddHandler bw.RunWorkerCompleted, AddressOf bw_RunWorkerCompleted
AddHandler dp.OnProgressUpdate, AddressOf dp_OnProgressUpdate
End Sub
End Class
谢谢大家!
该事件仍然来自与 UI 不同的线程。您需要将唤醒委派回 UI。我不检查 InvokeRequired
因为我知道它来自工作线程。
Me
是表单,Invoke 请求委托来处理将数据带到 UI 线程的工作。这里我的委托 Sub
是一个 lambda Sub 而不是使用普通的 Sub 例程 - 更简单的设计。
Private Sub dp_OnProgressUpdate(ByVal status As String)
'invoke the UI thread to access the control
'this is a lambda sub
Me.Invoke(Sub
'safe to access the form or controls in here
txtResult.Text = status
End Sub)
End Sub
也许你可以尝试做这样的事情?
Private Delegate Sub del_Update(ByVal status As String)
Private Sub dp_OnProgressUpdate(ByVal status As String)
If txtResult.InvokeRequired Then
txtResult.Invoke(New del_Update(AddressOf dp_OnProgressUpdate), New Object() {status})
Else
target_textbox.text = status
End If
End Sub
我正在尝试使用事件从另一个 class 的后台工作者更新文本框。
这与 this SO post 中提到的问题相同,只是我使用的是 VB.NET。我正在尝试通过 @sa_ddam213.
实施第二个建议的解决方案我收到一个错误:“跨线程操作无效:控制 'txtResult' 从创建它的线程以外的线程访问。”
这是我的代码:
Public Class DataProcessor
Public Delegate Sub ProgressUpdate(ByVal value As String)
Public Event OnProgressUpdate As ProgressUpdate
Private Sub PushStatusToUser(ByVal status As String)
RaiseEvent OnProgressUpdate(status)
End Sub
Public Sub ProcessAllFiles(ByVal userData As UserData)
'Do the work
End Sub
End Class
Public Class MainForm
Private bw As New BackgroundWorker
Private dp As New DataProcessor
Private Sub bw_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)
Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)
If bw.CancellationPending = True Then
e.Cancel = True
Else
dp.ProcessAllFiles(CType(e.Argument, UserData))
End If
End Sub
Private Sub dp_OnProgressUpdate(ByVal status As String)
txtResult.Text = status
End Sub
Private Sub MainForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
bw.WorkerReportsProgress = True
bw.WorkerSupportsCancellation = True
AddHandler bw.DoWork, AddressOf bw_DoWork
AddHandler bw.ProgressChanged, AddressOf bw_ProgressChanged
AddHandler bw.RunWorkerCompleted, AddressOf bw_RunWorkerCompleted
AddHandler dp.OnProgressUpdate, AddressOf dp_OnProgressUpdate
End Sub
End Class
谢谢大家!
该事件仍然来自与 UI 不同的线程。您需要将唤醒委派回 UI。我不检查 InvokeRequired
因为我知道它来自工作线程。
Me
是表单,Invoke 请求委托来处理将数据带到 UI 线程的工作。这里我的委托 Sub
是一个 lambda Sub 而不是使用普通的 Sub 例程 - 更简单的设计。
Private Sub dp_OnProgressUpdate(ByVal status As String)
'invoke the UI thread to access the control
'this is a lambda sub
Me.Invoke(Sub
'safe to access the form or controls in here
txtResult.Text = status
End Sub)
End Sub
也许你可以尝试做这样的事情?
Private Delegate Sub del_Update(ByVal status As String)
Private Sub dp_OnProgressUpdate(ByVal status As String)
If txtResult.InvokeRequired Then
txtResult.Invoke(New del_Update(AddressOf dp_OnProgressUpdate), New Object() {status})
Else
target_textbox.text = status
End If
End Sub