C# SQLiteException(并且只有 SQLiteException)没有被抛出

C# SQLiteException (and only SQLiteException) not being thrown

我有一段代码:

try
{
    //sniping out a bunch of irrelevant code here
    result = cmd.ExecuteScalar();
    onExecution?.Invoke(result);
    return true;
}
catch (SQLiteException e)
{
    if (e.ResultCode == SQLiteErrorCode.Corrupt)
    {
        CorruptionDetected?.Invoke(null, EventArgs.Empty);
    }
    //snip - else if {etc}
    throw;
}

问题:我让 VS 设置为在所有异常情况下始终中断,无论发生什么情况,无一例外。 VS 正确地做到了这一点,并且除了这个之外,程序中所有其他异常都没有问题。

我知道为什么会发生错误。这对我来说绝对没有任何意义并且无关。

我想知道的是为什么这个问题似乎要么没有真正产生异常,要么没有捕捉到它。我 100% 确定错误正在发生。您可以在诊断工具 window 的“事件”选项卡中看到它们。它们堆积在那里,但我从来没有得到一个可捕获的异常,只是“事件”选项卡中无用的垃圾。

我该如何处理?如果错误(SQLite 错误(5):数据库已锁定)是一个问题,那么为什么我没有收到异常?如果这不是问题并且最终得到处理,为什么它会污染我的事件列表?

它目前的状态是完全不能接受的,因为它完全没有意义。在这种情况下我应该得到一个异常是一个问题,或者在这种情况下我不想被无用的调试事件淹没。

我最近在我们的 C#/C++ 代码中调查了同样的问题。我最终下载了 System.Data.SQLite 源代码并调试了库。 System.Data.SQLite DLL 是标准 SQLite (C++) 库的 C# 包装器。

最重要的:System.Data.SQLite DLL 使用异常,而 SQLite 使用 return 代码。包装器从 SQLite 中拦截 return 代码,并在合理的情况下将它们转换为异常。

如果 SQLite 代码 (SQLite.Interop) 是使用 INTEROP_LOG 标志编译的,库只会将某些错误记录到标准输出并且不会(可能是错误的??)将此通知包装器一种错误。因此 wrapper 不知道这个问题,不会抛出异常。

更深入:

如果您自己下载并编译了 System.Data.SQLite 库,请尝试在 SQLite.Interop\interop.c 文件中的函数 sqlite3InteropLogCallback 中设置一个断点。只要遇到 'database is locked' 错误,您的程序就会停止,但是不会抛出异常。