5

我创建了自己的行为如下:

public class BoundaryExceptionHandlingBehavior : IInterceptionBehavior
{


public IEnumerable<Type> GetRequiredInterfaces()
{
  return Type.EmptyTypes;
}

public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
{
  try
  {
    return getNext()(input, getNext);
  }
  catch (Exception ex)
  {
    return null; //this would be something else...
  }
}

public bool WillExecute
{
  get { return true; }
}

}

我已正确设置它,以便我的行为按预期受到影响。但是,如果在 getNext() 所做的任何事情中发生任何异常,它都不会击中我的 catch 块。谁能澄清为什么?我并不是真的想解决这个问题,因为有很多方法可以处理异常,更多的是我不明白发生了什么,我想这样做。

4

3 回答 3

8

您无法捕获任何异常,如果发生异常,它将成为IMethodReturn 的 Exception 属性的一部分

像这样:

public IMethodReturn Invoke(IMethodInvocation input,
                GetNextInterceptionBehaviorDelegate getNext)
{
   IMethodReturn ret = getNext()(input, getNext);
   if(ret.Exception != null)
   {//the method you intercepted caused an exception
    //check if it is really a method
    if (input.MethodBase.MemberType == MemberTypes.Method)
    {
       MethodInfo method = (MethodInfo)input.MethodBase;
       if (method.ReturnType == typeof(void))
       {//you should only return null if the method you intercept returns void
          return null;
       }
       //if the method is supposed to return a value type (like int) 
       //returning null causes an exception
    }
   }
  return ret;
}
于 2012-04-05T09:37:07.047 回答
1

我认为还有一点更重要。IMethodReturn.Exception如果在行为管道中更深地抛出异常,则不会处理和保存异常。InvokeInterceptionBehaviorDelegate因为 Unity通过使用块包围方法调用来创建拦截的方法包装器,即实例try-catch。但您的拦截器方法并非如此。您可以检查CreateDelegateImplementation()方法和InterceptionBehaviorPipeline类以获取有关如何完成的更多详细信息。

如果你想处理从其他更深的拦截器抛出的异常,你可以使用这样的东西:

public IMethodReturn Invoke(IMethodInvocation input,
                            GetNextInterceptionBehaviorDelegate getNext)
{
    try
    {
        return InvokeImpl(input, getNext);
    }
    catch (Exception exception)
    {
        // Process exception and return result
    }
}

private IMethodReturn InvokeImpl(IMethodInvocation input,
                                GetNextInterceptionBehaviorDelegate getNext)
{
    var methodReturn = getNext().Invoke(input, getNext);
    if (methodReturn.Exception != null)
        // Process exception and return result

    return methodReturn;
}
于 2015-05-15T11:43:04.577 回答
1

我知道这是一篇旧文章,但gideon的解决方案抛出了 Unity null 引用异常。我想在调用者中处理异常,而不是在 Unity 拦截中。

这是一个有效的解决方案,它在调用者身上抛出异常,而不是在拦截中:

public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
{
    IMethodReturn ret = getNext()(input, getNext);
    if (ret.Exception != null)
    {
        // Throw the Exception out of the Unity Interception
        ExceptionDispatchInfo.Capture(ret.Exception).Throw();
    }

    // Process return result
    return ret;
}

然后,当您调用拦截的方法时,您可以获得异常:

try
{
    // Method intercepted by Unity pipeline
    InterceptedMethod();
}
catch(Exception e)
{
    //Exception handling
}
于 2017-01-06T11:51:38.453 回答