【问题标题】:Delegate within a delegate in VB.NETVB.NET 中的委托中的委托
【发布时间】:2010-03-23 05:11:12
【问题描述】:

我正在尝试编写一个 VB.NET 替代 C# 匿名函数。

我希望调用 Threading.SynchronizationContext.Current.Send,它期望将 Threading.SendOrPostCallback 类型的委托传递给它。背景是here,但是因为我希望将字符串传递给MessageBox.Show 并捕获DialogResult,所以我需要在其中定义另一个委托。我在 VB.NET 语法中苦苦挣扎,无论是传统的委托风格还是 lambda 函数。

我对传统语法的看法如下,但我直觉它应该比这简单得多:

Private Sub CollectMesssageBoxResultFromUserAsDelegate(ByVal messageToShow As String, ByRef wasCanceled As Boolean)
    wasCanceled = False
    If Windows.Forms.MessageBox.Show(String.Format("{0}{1}Please press [OK] to ignore this error and continue, or [Cancel] to stop here.", messageToShow), "Continue", Windows.Forms.MessageBoxButtons.OKCancel, Windows.Forms.MessageBoxIcon.Exclamation) = Windows.Forms.DialogResult.Cancel Then
        wasCanceled = True
    End If
End Sub


Private Delegate Sub ShowMessageBox(ByVal messageToShow As String, ByRef canceled As Boolean)


Private Sub AskUserWhetherToCancel(ByVal message As String, ByVal args As CancelEventArgs)

    If args Is Nothing Then args = New System.ComponentModel.CancelEventArgs With {.Cancel = False}

    Dim wasCancelClicked As Boolean
    Dim firstDelegate As New ShowMessageBox(AddressOf CollectMesssageBoxResultFromUserAsDelegate)
    '…. Now what??
    'I can’t declare SendOrPostCallback as below: 
    'Dim myDelegate As New Threading.SendOrPostCallback(AddressOf firstDelegate) 


End Sub

【问题讨论】:

    标签: vb.net multithreading delegates lambda backgroundworker


    【解决方案1】:

    我认为处理这个问题的最简单方法是创建一个新对象来包装消息框的显示。然后可以使用该对象来检索结果。

    例如:

    Public Class Helper 
      Public WasCanceled as Boolean
      Public Message As String
      Public Done as New ManualResetEvent(false)
      Public Sub New(message as String) 
        Me.Message = message
      End Sub 
      Public Sub ShowMessageBox(unused as Object) 
        If MessageBox.Show(Message) = DialogResult.Cancel Then 
          WasCanceled = True
        Done.Set()
      End Sub 
    End Class
    
    Public Sub AskUserWhetherToCancel(context as SynchronizationContext, message As String)
      Dim helper As New Helper(message)
      context.Post(AddressOf helper.ShowMessageBox, Nothing)
    
      ' Wait for it to finish
      helper.WaitOne()
    
      if helper.WasCanceled Then 
        ...
      Else
        ...
      End IF
    End Sub
    

    【讨论】:

    【解决方案2】:

    试试这个:

    Dim myDelegate As New Threading.SendOrPostCallback(Function(c) firstDelegate) 
    

    不确定它是否会完全按照你的意愿工作,但它会编译。

    也许这就是你要找的东西:Passing parameters to delegates in VB.NET

    【讨论】:

    • 正确,它会自行编译,但我如何将参数(消息,wasCancelClicked)推入其中。然后我将如何调用: Threading.SynchronizationContext.Current.Send(AddressOf myDelegate) 如果这样做,我会收到错误:“'AddressOf' 操作数必须是方法的名称(不带括号)”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-12
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多