C# 未处理的异常是否绕过try/catch块?
我发现这个错误发生在我构建的webapi上:C# 未处理的异常是否绕过try/catch块?,c#,.net,iis,try-catch,unhandled-exception,C#,.net,Iis,Try Catch,Unhandled Exception,我发现这个错误发生在我构建的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
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()
对DB2的每个查询都被捕获,因此任何错误都应该被记录和管理。但是,由于这些错误,“有时”(并非总是)整个应用程序池都会崩溃
我之所以这样说,是因为事件查看器上的一些错误(它们是相同的)已被记录,但不会停止IIS池
它正在运行.NET v4.0
可能是什么?可以绕过try/catch吗?很奇怪
编辑:
大多数try/catch都是通用的:
try
{
}
catch (Exception ex)
{
}
有些是具体的,例如:
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)
{
//
}
int rowCount=0;
SqlBuilder.Template模板=null;
尝试
{
template=CreateSQLTemplate(过滤器,“行计数”);
使用(idb2connectiondb2=newidb2connection(Properties.Settings.Default.AS400Connection))
{
var rowCounts=db2.Query(template.RawSql,template.Parameters);
rowCount=rowCounts.Count()>0?rowCounts.First():0;
}
}
捕获(iDB2SQLErrorException db2Sqlex)
{
//
}
捕获(例外情况除外)
{
//
}
这就足够了,不是吗?NET Framework提供了几个事件,可用于捕获未处理的异常。当应用程序启动时,只需在代码中注册一次这些事件。对于ASP.NET,您可以在Startup类或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);
}
您是否尝试在连接字符串中设置
EnablePreFetch=false
您是否尝试订阅此活动? 自.NET framework 4.5以来,此行为已发生更改,但您可以使其拥有有关此异常来源的更多详细信息 此事件是一个静态事件,建议在应用程序启动时尽快订阅此事件 不要错过编辑配置文件
<runtime>
<ThrowUnobservedTaskExceptions enabled="true"/>
</runtime>
这是一个使用示例
请注意这一点
希望这有帮助尝试在数据库连接中打开连接池:
var connb = new DB2ConnectionStringBuilder(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
connb.Pooling = true;
connb.MinPoolSize = 1;
connb.MaxPoolSize = 100;
var conn = new DB2Connection(connb.ConnectionString);
如果您不能或不想这样做,请确保在完成db的每个连接后都显式关闭它。否则,当垃圾收集器拾取打开的连接对象时,可能会引发未处理的异常。这个问题以前在DB2提供程序中观察到过。根据堆栈跟踪,这个异常发生在DB2自动创建的线程中。它不运行您的任何代码,因此您无法使用
try
块捕获此异常
3F
前面的两个空格看起来可疑未处理的异常是尚未捕获的异常,即包装在
try..catch
块中。我们可以查看您的catch
吗?有些异常无法可靠地捕获(特别是内存不足、堆栈溢出和线程中止),但大多数异常都可以被捕获。如果您意外地看到异常:您可能没有捕获到您认为捕获到的内容,因为这会破坏整个过程:是的,如果异常到达堆栈顶部,就会发生这种情况。看起来你在运行自己的线程,所以。。。是的,不要这样(未处理的异常)happen@markzzz嗯,您添加的代码将无法编译-至少缺少一个大括号;现在还不清楚它们在你的其他代码中的位置,所以。。。这是不可能的comment@markzzz这种特殊情况是由于async void
如何工作以及如何在async
上下文中处理异常的组合造成的(它们通常附加到任务
对象,该对象对于异步无效
签名不存在,导致在原始线程中引发异常,无论该线程当时在何处)。因此在本例中,如果将签名更改为异步任务
(然后你应该正确地等待那项任务
。但主要是给出一个异常可以“绕过”try-catch块的示例。尝试了你的解决方案。但我仍然在事件查看器上看到未处理的异常,而且我没有看到任何(自定义)日志:(该死,这看起来很糟糕……我关闭了所有连接。)(如果您看到代码,则有“使用”)。连接池如何?我应该使用哪个标记?@markzzz是的,我看到了使用,但我想强调的是,您需要确保它在任何地方都被使用。您可以尝试使用Close()显式关闭连接吗最后?我知道这几乎是离奇的,但我不确定IBM是如何在幕后实现连接的。关于池,我更新了我的帖子。我在哪里订阅它?示例?我刚刚编辑了帖子,希望这有助于这不是TPL任务。调用堆栈清楚地显示没有未处理的TPL任务。这是IBM SQL Pro手动启动的线程在IBM的第二个链接解决方案中:您的调用堆栈显示异常发生在提供程序启动的线程内,该线程处理预取数据(性能方面的问题)。尝试关闭ConnectionString中的预回迁(EnablePreFetch=false),然后围绕长时间运行的查询进行异常处理。
第1点:我应该做什么?你能告诉我步骤吗?第2点:涉及的表/数据太多,我们无法对其进行个性化处理。说明了该做什么,但你需要能够通过附加的调试器重现问题。如果做不到这一点,我将尝试如前所述,se实时调试。