代码之家  ›  专栏  ›  技术社区  ›  rakete

VB.NET版委托不起作用

  •  0
  • rakete  · 技术社区  · 15 年前

    在我的应用程序中,我有一个带有ToolStripProgressBar和toolstrippstatuslabel的主窗口。

    此属性:

    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
    

    它不起作用。我有个例外:

    无效操作异常

    我收到了英文文本,无法很好地翻译成英文,但我想是这样的:

    不允许访问由另一个线程从另一个线程创建的控件。

    我使用的是visualstudio2008express+VB 2.0。

    谢谢您!

    3 回复  |  直到 15 年前
        1
  •  1
  •   Konrad Rudolph    15 年前

    这是由于不允许跨线程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's注释是正确的:您的调用应该是直接的方法调用,而不是委托调用。

        2
  •  1
  •   vulkanino    15 年前
    Dim statusToSub As **new** delegateStatusTo(AddressOf WriteToDebug)
    statusToSub.Invoke("Test")
    
    Dim percToSub As **new** delegatePercTo (AddressOf percTo)
    percToSub.Invoke(50)
    
        3
  •  1
  •   Brian Gideon    15 年前

    看起来您正试图从 DoWork 事件处理程序。请记住,该事件处理程序正在工作线程上运行。不允许从创建它的线程以外的其他线程中触摸任何UI控件。有一个 ProgressChanged 调用时将自动封送到UI线程上的事件 ReportProgress . 您可以从此事件安全地更新UI。