VB.NET 委托不起作用
在我的应用程序中,我有一个带有 ToolStripProgressBar 和 ToolStripStatusLabel 的 MainWindow。
此属性:
Property ProgressBarPercantage() As Integer Implements BCSXPSearchTool.Presenter.IMainView.ProgressPercentage
Get
Return Me._progressbarpercentage
End Get
Set(ByVal value As Integer)
Me._progressbarpercentage = value
Me.StatusStripCurrentProgressBar.Value = Me._progressbarpercentage
End Set
End Property
Private _progressbarpercentage As Integer = 0
Property ProgressStatusText() As String Implements BCSXPSearchTool.Presenter.IMainView.ProgressStatusText
Get
Return Me._progressstatustext
End Get
Set(ByVal value As String)
Me._progressstatustext = value
Me.StatusStripCurrentState.Text = Me._progressstatustext
End Set
End Property
Private _progressstatustext As String = "Ready"
在 MainWindowPresenter 中,我启动一个新的 BackgroundWorker,它应该从数据库中读取。
Public Sub Search()
Dim bw As New BackgroundWorker
bw.WorkerReportsProgress = True
bw.WorkerSupportsCancellation = True
AddHandler bw.DoWork, AddressOf runproc
If bw.IsBusy = False Then
bw.RunWorkerAsync()
End If
End Sub
Public Sub runproc()
Dim statusToSub As delegateStatusTo = AddressOf statusTo
Dim percToSub As delegatePercTo = AddressOf percTo
statusToSub.Invoke("Test")
'percToSub.Invoke(50)
End Sub
Public Sub percTo(ByVal value As Integer)
_view.ProgressPercentage = value
End Sub
Public Sub statusTo(ByVal value As String)
_view.ProgressStatusText = value
End Sub
Delegate Sub delegateStatusTo(ByVal value As String)
Delegate Sub delegatePercTo(ByVal value As Integer)
上面的代码正在运行。但如果我将 sub runproc() 更改为:
Public Sub runproc()
Dim statusToSub As delegateStatusTo = AddressOf statusTo
Dim percToSub As delegatePercTo = AddressOf percTo
' statusToSub.Invoke("Test")
percToSub.Invoke(50)
End Sub
它不起作用。我得到一个异常:
InvalidOperationException
我收到了英文文本,无法很好地将其翻译成英文,但我认为是这样的:
不允许从另一个线程访问由另一个线程创建的控件。
我正在使用 Visual Studio 2008 Express + VB 2.0。
谢谢你!
In my application, I have a MainWindow with a ToolStripProgressBar and a ToolStripStatusLabel.
This properties:
Property ProgressBarPercantage() As Integer Implements BCSXPSearchTool.Presenter.IMainView.ProgressPercentage
Get
Return Me._progressbarpercentage
End Get
Set(ByVal value As Integer)
Me._progressbarpercentage = value
Me.StatusStripCurrentProgressBar.Value = Me._progressbarpercentage
End Set
End Property
Private _progressbarpercentage As Integer = 0
Property ProgressStatusText() As String Implements BCSXPSearchTool.Presenter.IMainView.ProgressStatusText
Get
Return Me._progressstatustext
End Get
Set(ByVal value As String)
Me._progressstatustext = value
Me.StatusStripCurrentState.Text = Me._progressstatustext
End Set
End Property
Private _progressstatustext As String = "Ready"
In the MainWindowPresenter I start a new BackgroundWorker which should read from a database.
Public Sub Search()
Dim bw As New BackgroundWorker
bw.WorkerReportsProgress = True
bw.WorkerSupportsCancellation = True
AddHandler bw.DoWork, AddressOf runproc
If bw.IsBusy = False Then
bw.RunWorkerAsync()
End If
End Sub
Public Sub runproc()
Dim statusToSub As delegateStatusTo = AddressOf statusTo
Dim percToSub As delegatePercTo = AddressOf percTo
statusToSub.Invoke("Test")
'percToSub.Invoke(50)
End Sub
Public Sub percTo(ByVal value As Integer)
_view.ProgressPercentage = value
End Sub
Public Sub statusTo(ByVal value As String)
_view.ProgressStatusText = value
End Sub
Delegate Sub delegateStatusTo(ByVal value As String)
Delegate Sub delegatePercTo(ByVal value As Integer)
The code above is working. But if I change the sub runproc() to:
Public Sub runproc()
Dim statusToSub As delegateStatusTo = AddressOf statusTo
Dim percToSub As delegatePercTo = AddressOf percTo
' statusToSub.Invoke("Test")
percToSub.Invoke(50)
End Sub
It doesn't work. I get an exception:
InvalidOperationException
I got the text in english and can't translate it to english very well but I think something like:
The access to the control, created by another thread from another thread is not allowed.
I'm using Visual Studio 2008 Express + VB 2.0.
Thank you!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这是由于不允许跨线程 UI 访问(但对于每个 UI 访问,因此您的其他代码也不应该工作!)。最简单的解决方案是在需要时使用
BeginInvoke
:此外,@vulkanino 的评论很准确:您的调用应该是直接方法调用,而不是委托调用。
This is due to cross-thread UI access which is disallowed (but for every UI access, so your other code shouldn’t work either!). The easiest solution is to use
BeginInvoke
when required:Furthermore, @vulkanino’s comment is spot-on: your calls should be direct method calls, not delegate invocations.
您似乎正在尝试从
DoWork
事件处理程序访问 UI 控件。请记住,该事件处理程序在工作线程上运行。除了创建 UI 控件的线程之外,您不得从线程中触摸任何 UI 控件。有一个ProgressChanged
事件,在调用ReportProgress
时将自动编组到 UI 线程。您可以从此事件安全地更新 UI。It looks like you are attempting to access UI controls from the
DoWork
event handler. Remember, that event handler is running on a worker thread. You are not allowed to touch any UI control from a thread other than the one that created it. There is aProgressChanged
event that will be marshaled onto the UI thread automatically upon callingReportProgress
. You safely update the UI from this event.