【问题标题】:How to check if exception occured on disposing an event (.Net)如何检查在处理事件时是否发生异常(.Net)
【发布时间】:2016-04-12 22:56:53
【问题描述】:

在处理对象时,我想检查是否发生异常以选择是​​否执行 COMMIT。我正在使用针对 SAP 的 BAPI。

如果创建运输单 (1) 失败,我想取消物料单 (2)。 (但这不属于问题)

          Dim rfcFunction As IRfcFunction

    Try

        Using sapConn3 As New SapConnectorV3
          ' (1) Creation of a Transport-Order
        End Using

    Catch ex As Exception

        Using sapConn3 As New SapConnectorV3
          ' (2) Cancel MaterialDocument
          ' (EDIT) The problem can be fixed if I call 
          ' "CommitTransaction" manually at this line. But I want to do 
          ' this automatically on disposing the object
        End Using

        Throw

    End Try

当 Using-Block 结束时,对象被释放,此时我必须知道是否发生了异常。

这个函数不起作用,因为它在两次处理中都声明为 true:

 Protected ReadOnly Property ExceptionOccurred() As Boolean
    Get
        Return Runtime.InteropServices.Marshal.GetExceptionCode <> 0
    End Get
End Property

这就是我决定是否提交的方式(部分 Dispose():

 Public Sub Dispose() Implements IDisposable.Dispose

     If Not ExceptionOccurred Then

        CommitTransaction()

    End If

【问题讨论】:

    标签: .net vb.net exception-handling try-catch dispose


    【解决方案1】:

    你可以从相反的方向解决这个问题。不要在发生故障时通知您的 SapConnectionV3 对象,而是在您成功时告诉它。

    您只需将Complete() 或CompletedSuccessfully() 或类似方法添加到您的SapConnectorV3,这将设置一个私有bool 标志。在您离开 Using 块之前调用它。然后,在你的 Dispose 实现中,如果标志为真则提交,如果为假则回滚。

    那么你的调用约定变成:

    Using sapConn3 As New SapConnectorV3
        ' Do some work.
        sapConn3.Complete()
    End Using ' Now this will commit if Complete was called, or roll back otherwise.
    

    【讨论】:

    • 感谢您的回复。这就是我以类似的方式做的事情。我直接执行提交。如果我在尝试部分中并且发生异常,似乎没有真正的提示,或者?
    • @etalon11,这种语言根本不支持。异常信息不是环境信息。理论上,您可以通过将Action 传递给您的SapConnectorV3 实际上执行 临界区内的代码 - 然后它可以观察并重新抛出委托抛出的任何异常;但我不会称之为一个很好的解决方案。在 .NET 世界中,按照我在回答中的建议进行操作通常是可以接受的。
    【解决方案2】:

    我认为你有你的 Try Catch 和你使用错误的方式。我认为您需要的模式如下:

    Using sapConn3 As New SapConnectorV3
        Try   
          StartTransaction       
          ' (1) Creation of a Transport-Order
          CommitTransaction
        Catch ex As Exception
          ' (2) Cancel MaterialDocument
          RollbackTransaction
        End Try
    End Using
    

    检测到发生异常很简单,您将代码放在Catch 块中以获取此异常

    “因为发生了异常而被释放”- 对象没有被释放因为发生了异常,因此无法在对象本身内部检测到这一点。考虑这些:

        Using sapConn3 As New SapConnectorV3
            Try
                'do something
            Catch ex As Exception
                'exception is thrown but object is not yet disposed
            End Try
        End Using 'object is now disposed
    
    
        Try
            Using sapConn3 As New SapConnectorV3
                'do somework
            End Using 'object is disposed here
        Catch ex As Exception
            'object must have be dispoed at this point as we are outide the using block
        End Try
    

    因此,通过使用第一个选项,您无需检查对象本身的内部

    【讨论】:

    • 抱歉,这对我不起作用。材料文档已创建并已提交。在 SAP 中,您无法为未提交的物料文档创建运输订单。所以,请关注“如何检查是否发生异常”。我知道这有点奇怪,但它是一个带有事务处理的 SAP 接口,而不是一个关系数据库。感谢您的反馈。
    • “我如何检查是否发生异常”问题的答案是代码进入了 catch 块。您可能无法回滚事务,但您仍然可以撤销您所做的任何事情。
    • 我编辑了我的代码以向您展示我正在使用的解决方法。但不要挂断提交或回滚。我只想知道如何检查是否因为发生异常而释放了一个对象。
    • 对象不一定会因为发生异常而被释放,但在您的代码中,对象将在您的 catch 块中的代码运行时被释放,这就是您需要更改您使用和尝试块的顺序
    猜你喜欢
    • 2013-05-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-03
    • 1970-01-01
    相关资源
    最近更新 更多