简体   繁体   English

未处理的异常会绕过 try/catch 块吗?

[英]Do an unhandled exception bypass a try/catch block?

I've this error, which occurs on a webapi I build:我有这个错误,它发生在我构建的 webapi 上:

An unhandled exception occurred and the process was terminated.

Application ID: /LM/W3SVC/1/ROOT/MyWebAPI

Process ID: 43144

Exception: IBM.Data.DB2.iSeries.iDB2SQLErrorException

Message: SQ20377 Character X'  3F' cannot be mapped to a valid XML character.

StackTrace:    at IBM.Data.DB2.iSeries.iDB2Exception.throwDcException(MpDcErrorInfo mpEI, MPConnection conn)
   at IBM.Data.DB2.iSeries.iDB2Command.reportDCError(Int32 rc)
   at IBM.Data.DB2.iSeries.iDB2Command.fetch()
   at IBM.Data.DB2.iSeries.iDB2DataReader.MPDataReader.FetchData(UInt32& rowsReturned, UInt32& blockNumber)
   at IBM.Data.DB2.iSeries.iDB2DataReader.MPDataReader.FetchThread()
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()

Every query to DB2 are catched, so any error should be logged and managed.对 DB2 的每个查询都会被捕获,因此应记录和管理任何错误。 But instead, "sometimes" (not always) the whole application pool go down due to these errors.但相反,由于这些错误,“有时”(并非总是)整个应用程序池 go 会关闭。

I said sometimes because some of those errors on Event Viewers (which are the same) are logged, but don't stop the IIS pool.我有时说是因为记录了事件查看器(相同)上的一些错误,但不要停止 IIS 池。

Its running .NET v4.0.它正在运行 .NET v4.0。

What can it be?会是什么? Can a try/catch be bypassed?可以绕过 try/catch 吗? Very weird...很奇怪...

EDIT:编辑:

most try/catch are generic:大多数 try/catch 都是通用的:

try
{

}
catch (Exception ex)
{

}

some are specifics, such as:有些是具体的,例如:

int rowCount = 0;
SqlBuilder.Template template = null;

try
{
    template = CreateSQLTemplate(filters, "rowcount");

    using (iDB2Connection db2 = new iDB2Connection(Properties.Settings.Default.AS400Connection))
    {
        var rowCounts = db2.Query<int>(template.RawSql, template.Parameters);
        rowCount = rowCounts.Count() > 0 ? rowCounts.First() : 0;
    }
}
catch(iDB2SQLErrorException db2Sqlex)
{
    //
}
catch (Exception ex)
{
    //
}

This can be enough, can't be?这可能就足够了,不是吗?

The .NET Framework provides a couple events that can be used to catch unhandled exceptions. .NET 框架提供了几个可用于捕获未处理异常的事件。 You only need to register for these events once in your code when your application starts up.当您的应用程序启动时,您只需在代码中注册一次这些事件。 For ASP.NET, you would do this in the Startup class or Global.asax对于 ASP.NET,您可以在 Startup class 或 Global.asax 中执行此操作

static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
{
     // Log the exception, display it, etc
     Debug.WriteLine(e.Exception.Message);
}

static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
     // Log the exception, display it, etc
     Debug.WriteLine((e.ExceptionObject as Exception).Message);
}

Do you have tried to subscribe to this event?您是否尝试订阅此活动? TaskScheduler.UnobservedTaskException Event TaskScheduler.UnobservedTaskException 事件

This behavior is changed since .NET framework 4.5 but you can enable it to have maybe more details for the origin of this exception.自 .NET 框架 4.5 以来,此行为已更改,但您可以启用它以获取有关此异常起源的更多详细信息。

The event is a static one, it's recommended to subscribe to this event as soon as possible at the start of your application.该事件是一个 static 事件,建议在您的应用程序开始时尽快订阅此事件。

Don't miss editing the configuration file不要错过编辑配置文件

<runtime>
    <ThrowUnobservedTaskExceptions enabled="true"/>
</runtime>

This an example of use tpl-exception-handling这是一个使用tpl-exception-handling的例子

Notice this also Release mode注意这也是发布模式

Hope this helps希望这可以帮助

Try turning on connection pooling in your DB connection:尝试在您的数据库连接中打开连接池:

var connb = new DB2ConnectionStringBuilder(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
connb.Pooling = true;
connb.MinPoolSize = 1;
connb.MaxPoolSize = 100;
var conn = new DB2Connection(connb.ConnectionString);

If you can't or don't want to do that, make sure to explicitly close every single connection to the db after you're done with it.如果您不能或不想这样做,请确保在完成后明确关闭与数据库的每个连接。 Otherwise an unhandled exception may be thrown when the garbage collector picks up your open connection objects.否则,当垃圾收集器拾取您打开的连接对象时,可能会引发未处理的异常。 This problem has been observed before with the DB2 provider.之前使用 DB2 提供程序已观察到此问题。

According to the stack trace, this exception happens in a thread that DB2 creates automatically.根据堆栈跟踪,此异常发生在 DB2 自动创建的线程中。 It doesn't run any of your code so you can't catch this exception with a try block.它不会运行您的任何代码,因此您无法使用try块捕获此异常。

  1. Configure the Visual Studio debugger to break on unhandled exceptions.配置 Visual Studio 调试器以中断未处理的异常。
  2. Try to find out where that strange-looking character comes from.试着找出那个看起来很奇怪的角色是从哪里来的。 Those two blanks in front of the 3F look suspicious. 3F前面的那两个空白看起来很可疑。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM