C# 在挡块内运行时检测
如何检测当前正在执行的代码何时从catch块中被调用C# 在挡块内运行时检测,c#,catch-block,C#,Catch Block,如何检测当前正在执行的代码何时从catch块中被调用 void SomeFunction() { // how do I detect whether I am being called from within a catch block? } 编辑: 对于那些提出问题的人,我想实现这样一个类,更不用说错误冒泡逻辑了:在编写这个代码示例时,我得到了一个编译器错误“catch子句之外不允许有无参数的throw语句”,所以这有点破坏了我的想法 public class ErrorManag
void SomeFunction()
{
// how do I detect whether I am being called from within a catch block?
}
编辑:
对于那些提出问题的人,我想实现这样一个类,更不用说错误冒泡逻辑了:在编写这个代码示例时,我得到了一个编译器错误“catch子句之外不允许有无参数的throw语句”,所以这有点破坏了我的想法
public class ErrorManager {
public void OnException(Exception ex) {
LogException(ex);
if (IsInsideCatchBlockAlready()) {
// don't destroy the stack trace,
// but do make sure the error gets bubbled up
// through the hierarchy of components
throw;
} else {
// throw the error to make it bubble up
// through the hierarchy of components
throw ex;
}
}
void LogException(Exception ex) {
// Log the exception
}
bool IsInsideCatchBlockAlready() {
// How do I implement this?
}
}
你没有。没有办法知道,如果抛出异常,它是否会被捕获或使程序崩溃。您可以在编译时使用代码分析工具进行猜测,但在代码运行时,这不是一个选项。不,没有办法做到这一点 通过分析生成的(IL)代码可能会有一些偷偷摸摸的方法,但我很确定您不希望这样 这是标准控制台应用程序捕获异常的IL:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 34 (0x22)
.maxstack 1
IL_0000: nop
.try
{
IL_0001: nop
IL_0002: ldstr "OK"
IL_0007: call void [mscorlib]System.Console::WriteLine(string)
IL_000c: nop
IL_000d: nop
IL_000e: leave.s IL_0020
} // end .try
catch [mscorlib]System.Exception
{
IL_0010: pop
IL_0011: nop
IL_0012: ldstr "Err"
IL_0017: call void [mscorlib]System.Console::WriteLine(string)
IL_001c: nop
IL_001d: nop
IL_001e: leave.s IL_0020
} // end handler
IL_0020: nop
IL_0021: ret
} // end of method Program::Main
如果您可以分析当前代码(假设它位于“OK”
)是否在该块中,您可以提取尝试。。。捕捉
块。当然,这并不考虑调用其他方法
这听起来也是解决你问题的一个荒谬的办法,所以在你投入你不想要的事情之前,想想你是否真的想这样做。你问错了问题,我的朋友 大多数框架允许通过特定方法处理未捕获的异常。WPF、C#webforms、asp,所有这些都有一个“未处理的异常处理”例程,您可以在应用程序级别连接到该例程 例如,普通C#表单应用程序使用:
Application.ThreadException += new ThreadExceptionEventHandler(MyCommonExceptionHandlingMethod)
private static void MyCommonExceptionHandlingMethod(object sender, ThreadExceptionEventArgs t)
{
//Exception handling...
}
因此,您只需要声明exceptionmanager类,然后将该类连接到异常处理中,例如:
Application.ThreadException += new ThreadExceptionEventHandler(TellMyClass)
private static void TellMyClass(object sender, ThreadExceptionEventArgs t)
{
ExceptionManager.HandleException(sender, t);
}
但是,我使用的模式是:
public static class UnhandledExceptionManager {
Logger _logger;
public static void RegisterToHandleFormsException(){
_logger = new Logger();
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
Application.ThreadException += OnThreadException;
AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
}
public static void OnUnhandledException(object sender, UnhandledExceptionEventArgs e){
HandleException((Exception)e.ExceptionObject);
}
private static void HandleException(Exception exception, [CallerMemberName] string methodName = "")
{
try
{
_logger.Error(methodName, exception);
}
catch (Exception e)
{
Debug.WriteLine("({0}) {1}", methodName, e);
}
}
}
在Program.cs中使用的:
public static void Main(){
UnhandledExceptionManager.RegisterToHandleFormsException();
//etc
}
如其他答案所述,你不能。您可以通过向方法传递参数来伪造它,但这似乎是一种代码味道。Windows上的CLR异常只是另一种SEH。阅读经典:。显然,可以检测代码在SEH处理程序中运行,因为必须检测。包含所需的所有内容,前提是您是操作系统或调试器,并且知道如何解释它
对你来说,我强烈建议你退后一步,走记录在案的道路。如果需要,请包装您的登录到try/catch块,以避免从要求不抛出的代码中泄漏异常。确保你处理得当,因为它很特别。挂接到适当的日志记录和错误报告中,并/或(视情况而定)。您始终可以用简单的方法完成:
void SomeFunction(bool isCalledFromCatch)
{
// how do I detect whether I am being called from within a catch block?
}
try
{
}
catch(...)
{
SomeFunction(true);
}
你没有。如果您认为有必要,那么您就是做错了;看看接下来会发生什么:)只是开玩笑。解释一下你为什么需要这个,我们可以帮你解决这个XY问题。或者,通过引入
bool throwIfNotFound
参数或您想要实现的任何功能,让您的方法根据需要抛出异常。一个方法永远不应该依赖于调用它的人或方法,这就是参数的用途。我想hackybool catch=true
是不可能的。我强烈建议你告诉我们你试图实现什么,因为你几乎肯定会走上一条非常糟糕的道路。