C# 正确使用CancelEventAgrs

C# 正确使用CancelEventAgrs,c#,.net,vb.net,event-handling,C#,.net,Vb.net,Event Handling,如何正确使用CancelEventAgrs/CancelEventHandler 检查e.Cancel是否总是返回“正确”的结果,即使事件最终可能会花费一些时间 Class Foo Public Event Deleting As System.ComponentModel.CancelEventHandler Private myObjectsToDelete As List(Of Object) Function DoDelete() As Boolean Dim e

如何正确使用CancelEventAgrs/CancelEventHandler

检查
e.Cancel
是否总是返回“正确”的结果,即使事件最终可能会花费一些时间

Class Foo
  Public Event Deleting As System.ComponentModel.CancelEventHandler

  Private myObjectsToDelete As List(Of Object)

  Function DoDelete() As Boolean
    Dim e As New System.ComponentModel.CancelEventArgs
    ' Suppose a time consumming check '
    RaiseEvent Deleting(myObjectsToDelete, e)

    If e.Cancel Then
      Return False
    Else
      myObjectsToDelete.Clear()
      Return True
    End If
  End Function
End Class

Class Bar
  Private WithEvents myFoo As Foo

  Private Sub myFoo_Deleting( _
        sender As Object,
        e As System.ComponentModel.CancelEventArgs) Handles myFoo.Deleting

    Dim objectsList As List(Of Object) = TryCast(sender, List(Of Object))
    Dim objectsToDeleteOK As New List(Of Object)
    For Each o In objectsList
      If CheckIfCanBeDeleted(o) Then
        objectsToDeleteOK.Add(o)
      End If
    Next o

  End Sub

  Private Function CheckIfCanBeDeleted(o As Object) As Boolean
    Dim result As Boolean
    ' TIME CONSUMMING CHECK '
    Return result
  End Function

End Class
PS.
我之所以使用C#标记,是因为我对通用的.NET视图感兴趣,而不仅仅是VB.NET视图

检查e.Cancel是否总是返回“正确”的结果,即使事件最终可能会花费一些时间

Class Foo
  Public Event Deleting As System.ComponentModel.CancelEventHandler

  Private myObjectsToDelete As List(Of Object)

  Function DoDelete() As Boolean
    Dim e As New System.ComponentModel.CancelEventArgs
    ' Suppose a time consumming check '
    RaiseEvent Deleting(myObjectsToDelete, e)

    If e.Cancel Then
      Return False
    Else
      myObjectsToDelete.Clear()
      Return True
    End If
  End Function
End Class

Class Bar
  Private WithEvents myFoo As Foo

  Private Sub myFoo_Deleting( _
        sender As Object,
        e As System.ComponentModel.CancelEventArgs) Handles myFoo.Deleting

    Dim objectsList As List(Of Object) = TryCast(sender, List(Of Object))
    Dim objectsToDeleteOK As New List(Of Object)
    For Each o In objectsList
      If CheckIfCanBeDeleted(o) Then
        objectsToDeleteOK.Add(o)
      End If
    Next o

  End Sub

  Private Function CheckIfCanBeDeleted(o As Object) As Boolean
    Dim result As Boolean
    ' TIME CONSUMMING CHECK '
    Return result
  End Function

End Class
您是否担心
DoDelete
会在事件处理程序执行完成之前测试
e.Cancel
的值

引发事件是一个阻塞操作,因此在执行所有处理程序之前,
DoDelete
的执行不会继续。因此,是的,
e.Cancel
将始终返回处理程序设置的值,即使处理程序需要一些时间来执行

检查e.Cancel是否总是返回“正确”的结果,即使事件最终可能会花费一些时间

Class Foo
  Public Event Deleting As System.ComponentModel.CancelEventHandler

  Private myObjectsToDelete As List(Of Object)

  Function DoDelete() As Boolean
    Dim e As New System.ComponentModel.CancelEventArgs
    ' Suppose a time consumming check '
    RaiseEvent Deleting(myObjectsToDelete, e)

    If e.Cancel Then
      Return False
    Else
      myObjectsToDelete.Clear()
      Return True
    End If
  End Function
End Class

Class Bar
  Private WithEvents myFoo As Foo

  Private Sub myFoo_Deleting( _
        sender As Object,
        e As System.ComponentModel.CancelEventArgs) Handles myFoo.Deleting

    Dim objectsList As List(Of Object) = TryCast(sender, List(Of Object))
    Dim objectsToDeleteOK As New List(Of Object)
    For Each o In objectsList
      If CheckIfCanBeDeleted(o) Then
        objectsToDeleteOK.Add(o)
      End If
    Next o

  End Sub

  Private Function CheckIfCanBeDeleted(o As Object) As Boolean
    Dim result As Boolean
    ' TIME CONSUMMING CHECK '
    Return result
  End Function

End Class
您是否担心
DoDelete
会在事件处理程序执行完成之前测试
e.Cancel
的值


引发事件是一个阻塞操作,因此在执行所有处理程序之前,
DoDelete
的执行不会继续。因此,是的,
e.Cancel
将始终返回处理程序设置的值,即使处理程序需要一些时间来执行。

如果将
e.Cancel
设置为
True
,则为是。您的处理程序似乎没有设置它。如果有多个处理程序处理该事件,则最后一个更改
e.Cancel
的处理程序获胜。

如果将
e.Cancel
设置为
True
,则为是。您的处理程序似乎没有设置它。如果有多个处理程序处理该事件,则最后一个更改
e.Cancel
的处理程序将获胜。

我不确定
RaiseEvent Deleting(myObjectsToDelete,e)
是否会等待,直到执行完所有检查。Raise事件会在引发它的线程上等待。所有处理程序都将在该线程上被调用,因为事件最终会导致方法调用。如果这些调用必须在另一个线程上设置
e.Cancel
,则必须将结果同步回来。我不确定
RaiseEvent Deleting(myObjectsToDelete,e)
是否等待直到执行所有检查。Raise事件在其引发的线程上等待。所有处理程序都将在该线程上被调用,因为事件最终会导致方法调用。如果这些调用必须在不同的线程上设置
e.Cancel
,那么您必须将结果同步回来。