VB.NET中委托中的委托

VB.NET中委托中的委托,vb.net,multithreading,delegates,lambda,backgroundworker,Vb.net,Multithreading,Delegates,Lambda,Backgroundworker,我正在尝试编写一个VB.NET替代C#匿名函数 我希望调用Threading.SynchronizationContext.Current.Send,它希望向其传递Threading.SendOrPostCallback类型的委托。背景是,但因为我希望向MessageBox.Show传递一个字符串,并捕获DialogResult,所以我需要在其中定义另一个委托。我正在努力学习VB.NET语法,既有传统的委托风格,也有lambda函数 我对传统语法的理解如下,但我直觉认为应该比这简单得多: Pri

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

我希望调用Threading.SynchronizationContext.Current.Send,它希望向其传递Threading.SendOrPostCallback类型的委托。背景是,但因为我希望向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
试试这个:

Dim myDelegate As New Threading.SendOrPostCallback(Function(c) firstDelegate) 
不确定它是否会完全按照您喜欢的方式工作,但它会编译

也许这就是你想要的:

试试这个:

Dim myDelegate As New Threading.SendOrPostCallback(Function(c) firstDelegate) 
不确定它是否会完全按照您喜欢的方式工作,但它会编译


也许这就是您要寻找的:

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

例如:

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

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

例如:

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

正确,它将自己编译,但是我如何将参数(消息,wasCancelClicked)推入其中。然后我将如何调用:Threading.SynchronizationContext.Current.Send(AddressOf myDelegate)如果我这样做,我将收到错误:“'AddressOf'操作数必须是一个方法的名称(不带括号)”正确,它将自行编译,但我如何将参数(消息,wasCancelClicked)推到该参数中。然后我将如何调用:Threading.SynchronizationContext.Current.Send(AddressOf myDelegate),如果我这样做,我将收到错误:“'AddressOf'操作数必须是一个方法的名称(不带括号)”太好了,谢谢Jared这工作得很好。我在表单构造函数中获取表单的SynchronizationContext,并将其用作发布到的上下文。我不需要等待一个或使用ManualResetEvent,因为我正在执行Post(同步)而不是发送(异步)。更多关于SynchronizationContext的参考:很好,谢谢Jared,这很好。我在表单构造函数中获取表单的SynchronizationContext,并将其用作发布到的上下文。我不需要等待一个或使用ManualResetEvent,因为我正在执行Post(同步)而不是发送(异步)。更多对SynchronizationContext的引用:和