我正在用C#WinForm打开一个SQLite数据库,并试图处理异常,并得到一个奇怪的错误。我已经实现了这段代码
bool TryingtoStart = true;
while (TryingtoSTart)
{
try
{
dbc.Open();
departmentDataAdapter = new SQLiteDataAdapter("select * from DEPARTMENT", dbc);
// etc
}
catch (SQLiteException ex)
{
DialogResult r = MetroFramework.MetroMessageBox.Show(this, ex.Message.ToString(), "Database error", MessageBoxButtons.RetryCancel);
if (r == DialogResult.Cancel) TryingtoStart = false;
}
catch (Exception exc)
{
DialogResult r = MetroFramework.MetroMessageBox.Show(this, exc.Message.ToString(), "Exception", MessageBoxButtons.RetryCancel);
if (r == DialogResult.Cancel) TryingtoStart = false;
}
if (!TryingtoStart) Application.Exit();
}
并得到错误
"Operation is not valid due to the current state of the object."
什么时候跑。这来自第二个catch(),即它不是SQLException。如果我删除我的捕获,我得到错误
System.InvalidOperationException: Operation is not valid due to the current state of the object.
at System.Data.SQLite.SQLiteConnection.Open()
使用open()调用的行号
如果我删除while循环和try / catch,一切正常。此代码位于Form_Load()方法中。
我试过但是无法理解这一点。我已经评论/取消注释了几次,错误是一致的。
如果在第一次尝试中一切顺利,没有异常,则不会退出循环。这意味着你再次运行dbc.Open();
- 一旦它已经打开。
这就是导致例外的原因。
顺便说一句,数据适配器隐式打开连接,如果它已关闭,所以你甚至不需要dbc.Open()
代码行。
更好地实现代码将是这样的:
bool TryingtoStart = true;
while (TryingtoSTart)
{
using(var dbc = new SQLiteConnection(connectionString))
{
try
{
using(var departmentDataAdapter = new SQLiteDataAdapter("select * from DEPARTMENT", dbc))
{
// etc
}
// Note: This row will only be executed if there where no exceptions until this point in the code
TryingtoStart = false;
}
catch (SQLiteException ex)
{
if (MetroFramework.MetroMessageBox.Show(this, ex.Message.ToString(), "Database error", MessageBoxButtons.RetryCancel) == DialogResult.Cancel) Application.Exit();
}
catch (Exception exc)
{
if (MetroFramework.MetroMessageBox.Show(this, exc.Message.ToString(), "Exception", MessageBoxButtons.RetryCancel) == DialogResult.Cancel) Application.Exit();
}
}
}
注意我在SQLiteConnection
语句中创建了SQLiteDataAdapter
和using
- 因为它们都实现了IDisposable
接口。