C# 未处理的异常是否绕过try/catch块?

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

我发现这个错误发生在我构建的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()
对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
块捕获此异常

  • 将Visual Studio调试器配置为在出现未处理的异常时中断
  • 试着找出那个奇怪的角色是从哪里来的。
    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实时调试。