myconnection.Close(); File.Delete(filename);
并且删除会抛出该文件仍在使用的异常。我在几分钟后重新尝试了调试器中的Delete(),所以这不是时间问题。
我有事务代码,但它不会在Close()调用之前运行。所以我相当肯定这不是一个开放的事务。 sql命令之间的打开和关闭只是选择。
ProcMon显示我的程序和我的防病毒程序查看数据库文件。它不显示我的程序在close()之后释放db文件。
Visual Studio 2010,C#,System.Data.sqlite版本1.0.77.0,Win7
我看到一个两岁的错误就像这样,但changelog说它是固定的。
还有什么我可以检查吗?有没有办法获得任何打开的命令或事务的列表?
新的,工作代码:
db.Close(); GC.Collect(); // yes,really release the db bool worked = false; int tries = 1; while ((tries < 4) && (!worked)) { try { Thread.Sleep(tries * 100); File.Delete(filename); worked = true; } catch (IOException e) // delete only throws this on locking { tries++; } } if (!worked) throw new IOException("Unable to close file" + filename);
无论如何,今天下午,我一直在看着这一切,想到我会尝试,找出为什么它一劳永逸,所以这里是我发现到目前为止。
当调用sqliteConnection.Close()时会发生什么事情(以及一些检查和其他事情)指向sqlite数据库实例的sqliteConnectionHandle被处理。这是通过调用sqliteConnectionHandle.Dispose()来实现的,但是这不会释放指针,直到CLR的垃圾收集器执行一些垃圾收集。因为sqliteConnectionHandle覆盖CriticalHandle.ReleaseHandle()函数来调用sqlite3_close_interop()(通过另一个函数),这并不关闭数据库。
从我的角度来看,这是一个非常糟糕的方式来做事情,因为程序员实际上并不确定当数据库被关闭,但这是它的方式,所以我想我们必须现在生活与现在,或提交对System.Data.sqlite的几个更改。欢迎任何志愿者这样做,不幸的是我没有时间在明年之前这样做。
TL; DR
解决方案是在调用sqliteConnection.Close()之后并在调用File.Delete()之前强制使用GC。
这里是示例代码:
string filename = "testFile.db"; sqliteConnection connection = new sqliteConnection("Data Source=" + filename + ";Version=3;"); connection.Close(); GC.Collect(); File.Delete(filename);
祝你好运,我希望它有所帮助