我一直在使用SQL Server CE 3.5 SP2数据库的.NET CF应用程序中发现这个随机问题。存在文件共享冲突。 SQL Server CE 3.5 SP2
当CF应用程序启动时,它执行数据库维护验证.SDF
数据库文件使用SQL Server CE Engine
类检查:
using (SqlCeEngine engine = new SqlCeEngine(Resources.SqlCeConnectionString))
{
Log.Info("Starting database Verification.");
if (!engine.Verify())
{
Log.Warn("Database failed verification.");
engine.Repair(null, RepairOption.RecoverAllOrFail);
Log.Info("Database successfully repaired.");
}
else
{
Log.Info("Database Verification successful.");
}
}
如果应用程序验证正确的话,我复制.SDF
成备份文件夹:
if (File.Exists(Resources.DatabaseFileLocation))
{
File.Delete(Resources.BackupDatabaseFileLocation);
File.Copy(Resources.DatabaseFileLocation, Resources.BackupDatabaseFileLocation);
Log.Info("Database backup complete.");
}
else
{
Log.Info("Could not find Device Database.");
}
一旦备份完成后,应用程序启动和第一连接的应用程序尝试与该.SDF
所导致此异常:
There is a file sharing violation. A different process might be using the file.
这里是日志文件的信息:
2013-05-13 11:52:29,894 [INFO ] - Starting database Verification.
2013-05-13 11:52:33,832 [INFO ] - Database Verification successful.
2013-05-13 11:52:33,838 [INFO ] - Database backup starting.
2013-05-13 11:52:46,941 [INFO ] - Database backup complete.
2013-05-13 11:52:47,933 [ERROR] - There is a file sharing violation. A different process might be using the file. [ \Program Files\ApplicationName\DB.sdf ]
at System.Data.SqlServerCe.SqlCeConnection.ProcessResults(Int32 hr) at System.Data.SqlServerCe.SqlCeConnection.Open(Boolean silent)
at System.Data.SqlServerCe.SqlCeConnection.Open()
at CFApp.MainScreen.GetStartupData()
at CFApp.MainScreen..ctor()
at CFApp.Program.RunInReleaseMode()
at CFApp.Program.Main()
我一直在研究这个问题的原因星期了,我无法找到任何东西。任何指导或帮助将非常感激。
基于我的努力到目前为止,我可以证实这些东西
- 问题发生随机。启动过程正确执行多次,然后它会随机抛出此错误
- 考虑到应用程序刚刚处于启动过程中,此时没有其他连接正在对数据库进行。
- 每次应用程序打开连接时,它会在完成后立即处理它。这是通过
using
声明完成的。如果意外关机/重新启动,没有打开的连接保持打开状态。 SqlCeEngine
正在处理与using
声明。物体被丢弃时到连接关闭时是否有延迟?- 目前没有其他进程在运行。该设备被锁定为仅允许我的应用程序被执行的 。经理 经理只显示
ActiveSync
和我的应用程序。该设备偶尔使用OpenNETCF.Desktop.Communication
通过USB与另一个桌面应用程序进行通信。有效 必须打开同步才能使其正常工作。它与之通信的台式计算机是Win XP。 我在其他一些论坛上看到,ActiveSync可能会在文件上保留一个 锁,这可能会导致问题。在设备的ActiveSync 部分中,没有选择与 桌面同步。 “文件”复选框未选中。如果其他人对我如何确保从 ActiveSync中排除此文件有任何 建议,这也会非常有帮助。
UPDATE - 我用dotPeek来看看
SqlCeEngine
Dispose方法。我认为一切似乎都是为了这里,我的 连接应该妥善处理?private void Dispose(bool disposing) { if (!disposing) return; this.connStr = (string) null; this.connTokens = (Hashtable) null; NativeMethods.DllRelease(); this.isDisposed = true; }
UPDATE - 我试图运行这个测试,看看我是否能重现错误,我想出了什么。代码正确执行并且应用程序开始运行,而不会发生任何文件共享问题。
for (int i = 0; i < 50; i++) { using (SqlCeEngine engine = new SqlCeEngine(Resources.SqlCeConnectionString)) { //Log.Info("Starting database Verification."); if (!engine.Verify()) { Log.Warn("Database failed verification."); engine.Repair(null, RepairOption.RecoverAllOrFail); Log.Info("Database successfully repaired."); } else { Log.Info("Verified" + i); } } if (File.Exists(Resources.BackupDatabaseFileLocation)) { File.Delete(Resources.BackupDatabaseFileLocation); } File.Copy(Resources.DatabaseFileLocation, Resources.BackupDatabaseFileLocation); Log.Info("File Copied " + i); GetStartupData(); }
非常感谢您事先的任何信息可以提供。
我只能假设数据库验证或备份还没有关闭文件。当您尝试访问数据库时,文件操作可能会缓存并仍在后台运行。对于file.write等我们有一个明确的Flush()方法,但我没有看到file.copy。如果将数据库访问权限(open)放在try catch块中,并在几次睡眠之间重试访问,会发生什么? – josef
@josef明天我会尝试第一件事。我认为这是保持文件打开的方法之一,但我不知道哪一个。我知道SqlCeEngine打开一个FileMode = Exclusive的连接,如果有东西试图访问它,会导致错误,但是我立刻处理它,应该释放锁。我想知道File.Copy是否也会拥有独占锁定? – neverseenjack