是否有可能在某些异常上不中断执行流,但在其他异常上中断执行流?如果可以,如何中断?
本文关键字:中断 异常 执行流 何中断 如果可以 其他 是否 有可能 | 更新日期: 2023-09-27 18:08:49
我需要从外部框架调用几个方法-或者更确切地说,我正在编写一个包装器,以便其他用户以非预定顺序从该框架调用方法。现在框架的一些方法会抛出异常,即使没有"真正的"错误发生。基本上,它们应该是内部异常,只是通知要执行的操作之前已经执行过。例如:文件已经加载。它不会伤害加载文件另一个时间,所以我关心这个"错误"根本不是错误。所以我需要继续讨论这个异常,但我也需要捕捉其他的,真正的异常,比如当框架,连接到客户端和东西,不能这样做。
下面我有一些(非常简化的)示例代码。显然,这些代码无法编译,因为缺少用于自定义异常的代码。同样,在现实生活中,代码分布在三个程序集中。这意味着,我不能将异常处理程序包装在那些只抛出InternalFrameworkException()
的框架方法周围。我只能把它包裹在整个SomeMethod()
上。正如我所写的,这是一个极其简化的例子。
是否有任何方法来处理RealException()s
,但继续InternalFrameworkException()s
不使用此处提到的PostSharp ?请注意,这并不是说让InternalFrameworkException()
掉下来,而是它们实际上根本不应该脱离try{}
块。
namespace ExceptionTest
{
using System;
internal class Program
{
private static void Main(string[] args)
{
try
{
SomeMethod();
}
catch (InternalFrameworkException exception)
{
// Do not actually catch it - but also dont break the
// execution of "SomeMethod()".
// Actually I never want to end up here...
}
catch (RealException exception)
{
// Break the execution of SomeMethod() as usual.
throw;
}
catch (Exception exception)
{
// Again, break the execution of SomeMethod() as usual.
throw;
}
finally
{
// Clean up.
}
}
#region == Method is actually contained in another assembly referencing this assembly ===
private static void SomeMethod()
{
// Should break if uncommented.
// MethodThrowingProperException();
// Should not break.
MethodThrowingInternalExceptionOrRatherContinuableError();
// Should execute, even if previously an internal framework error happened.
MethodNotThrowingException();
}
#endregion
#region ===== Framework methods, they are contained in a foreign dll =====
private static void MethodThrowingProperException()
{
// Something happened which should break execution of the
// application using the framework
throw new RealException();
}
private static void MethodThrowingInternalExceptionOrRatherContinuableError()
{
// Perform some stuff which might lead to a resumable error,
// or rather an error which should not break the continuation
// of the application. I.e. initializing a value which is
// already initialized. The point is to tell the application using
// this framework that the value is already initialized, but
// as this wont influence the execution at all. So its rather
// a notification.
throw new InternalFrameworkException();
}
private static void MethodNotThrowingException()
{
// Well, just do some stuff.
}
#endregion
}
}
编辑:我确实尝试了我上面已经链接的帖子中的例子,它像一个魅力…仅在SomeMethod()
中使用时。我理论上可以实现这一点,因为我在将SomeMethod()
中调用的所有方法暴露给最终程序集之前包装它们,但我不喜欢这种方法,因为它会给我的代码带来不必要的复杂性。当抛出异常时,执行流中断。你可以捕捉异常,也可以不捕捉,但是你不能在抛出异常后"继续"。
你可以把你的逻辑分成几个部分,当抛出一个异常时继续下一部分。
在这种情况下,我不确定除了AOP方法之外还有什么方法。如果您无法更改SomeMethod()
或它调用的任何方法,则需要考虑用捕获'可持续性'异常的方面来修饰被调用的方法,如MethodThrowingInternalExceptionOrRatherContinuableError()
。
方面将有效地将方法调用包装在try{...} catch(InternalFrameworkException)
(或类似的可捕获异常)块中。
正如你已经注意到的,一旦一个方法抛出了一个异常,即使调用者在catch()
块中捕获了异常,你也无法回到这个方法中,所以你需要注入到你正在调用的方法中,像PostSharp这样的AOP框架将允许你这样做。
我通过在try-catch(InternalFrameworkException)块中包装对InternalFrameworkMethod()的调用并调用它类似于internalframeworksafe(),然后在someemethod中调用处理过的InternalFrameworkMethodSafe()来解决类似的问题。
void InternalFrameworkMethodSafe()
{
try
{
InternalFrameworkMethod();
}
catch(InternalFrameworkException e)
{
Trace.Write("error in internal method" + e);
}
}
void SomeMethod()
{
...
InternalFrameworkMethodSafe();
...
}
如果内部框架处于错误状态而无法继续,则可能无法在您的情况下工作。