VB.NET 委托不起作用

发布于 2024-09-25 23:16:34 字数 2300 浏览 3 评论 0原文

在我的应用程序中,我有一个带有 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 技术交流群。

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

发布评论

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

评论(3

倚栏听风 2024-10-02 23:16:34

这是由于不允许跨线程 UI 访问(但对于每个 UI 访问,因此您的其他代码也不应该工作!)。最简单的解决方案是在需要时使用 BeginInvoke

Public Sub statusTo(ByVal value As String)
    If InvokeRequired Then
        BeginInvoke(New Action(Of String)(AddressOf statusTo))
        Return
    End If
    _view.ProgressStatusText = value
End Sub

此外,@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:

Public Sub statusTo(ByVal value As String)
    If InvokeRequired Then
        BeginInvoke(New Action(Of String)(AddressOf statusTo))
        Return
    End If
    _view.ProgressStatusText = value
End Sub

Furthermore, @vulkanino’s comment is spot-on: your calls should be direct method calls, not delegate invocations.

紧拥背影 2024-10-02 23:16:34
Dim statusToSub As **new** delegateStatusTo(AddressOf WriteToDebug)
statusToSub.Invoke("Test")

Dim percToSub As **new** delegatePercTo (AddressOf percTo)
percToSub.Invoke(50)
Dim statusToSub As **new** delegateStatusTo(AddressOf WriteToDebug)
statusToSub.Invoke("Test")

Dim percToSub As **new** delegatePercTo (AddressOf percTo)
percToSub.Invoke(50)
丘比特射中我 2024-10-02 23:16:34

您似乎正在尝试从 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 a ProgressChanged event that will be marshaled onto the UI thread automatically upon calling ReportProgress. You safely update the UI from this event.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文