Windows mobile 存在文件共享冲突。SQL Server CE 3.5 SP2

Windows mobile 存在文件共享冲突。SQL Server CE 3.5 SP2,windows-mobile,compact-framework,sql-server-ce,windows-mobile-6.5,Windows Mobile,Compact Framework,Sql Server Ce,Windows Mobile 6.5,我在使用SQLServerCE3.5SP2数据库的.NETCF应用程序中遇到了这个随机问题 当CF应用程序启动时,它会执行数据库维护,以验证要使用SQL Server CE引擎检查的.SDF数据库文件 using (SqlCeEngine engine = new SqlCeEngine(Resources.SqlCeConnectionString)) { Log.Info("Starting database Verification."); if (!engine.Verif

我在使用SQLServerCE3.5SP2数据库的.NETCF应用程序中遇到了这个随机问题

当CF应用程序启动时,它会执行数据库维护,以验证要使用SQL Server CE
引擎检查的
.SDF
数据库文件

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
    。在处理对象到关闭其连接之间是否存在可能的延迟
  • 此时没有其他进程正在运行。这个装置是 锁定为仅允许执行我的应用程序。任务 manager仅显示
    ActiveSync
    和我的应用程序。这个装置偶尔会出现 使用与其他桌面应用程序通信
    OpenNETCF.Desktop.Communication
    RAPI库通过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;
    }
    
  • 更新-我尝试运行此测试以查看是否可以重现错误,但没有发现任何结果。代码正确执行,应用程序正常启动,没有任何文件共享问题

    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();
    }
    
    for(int i=0;i<50;i++)
    {
    使用(SqlCeEngine=newsqlceengine(Resources.SqlCeConnectionString))
    {
    //Log.Info(“启动数据库验证”);
    如果(!engine.Verify())
    {
    Log.Warn(“数据库验证失败”);
    engine.Repair(null,RepairOption.RecoverAllOrFail);
    Log.Info(“数据库已成功修复”);
    }
    其他的
    {
    日志信息(“已验证”+i);
    }
    }
    if(File.Exists(Resources.backupdatebasefilelocation))
    {
    Delete(Resources.backupdatebasefilelocation);
    }
    Copy(Resources.DatabaseFileLocation,Resources.backupdatebasefilelocation);
    Log.Info(“文件复制”+i);
    GetStartupData();
    }
    

非常感谢您提供的任何信息。

我发现并不是所有类都像预期的那样实现了
IDisposable
。例如,当使用
语句从
调用时,Microsoft的OLE JET数据库引擎将不会关闭数据库连接

你可能有这些问题

首先,我建议在连接上显式调用
Close()
。如果这不能解决问题,您可以添加对
Dispose()
的显式调用


也可能是垃圾收集器(GC)在应用程序尝试再次访问之前,没有机会处理所有的
IDisposable
代码。

我只能假设数据库验证或备份尚未关闭文件。当您尝试访问数据库时,文件操作可能会被缓存并仍在后台运行。对于file.write等,我们有一个显式的Flush()方法,但对于file.copy,我看不到。如果您将数据库访问(打开)放在一个try-catch块中,并在其间进行一些睡眠,然后重试访问几次,会发生什么情况?@josef我明天将首先尝试。我假设这是保持文件打开的方法之一,但我不知道是哪一种。我知道SqlCeEngine打开了一个FileMode=Exclusive的连接,如果有东西试图访问它,这将导致错误,但我立即处理了它,这将释放锁。我想知道File.Copy是否也会对其进行独占锁定?我也想到了这一点,但我发现有两件事让我相信不是这样的:1。这个帖子是-2。SqlCeEngine不提供显式的“Close”方法。我使用dotPeek查看该类,它的Dispose方法似乎正确地清理了资源。在using语句中调用Dispose()是多余的……我发现ActiveSync也不是可疑的。当您的设备进入或退出暂停模式时,您能否监听并处理?如果是这样,您可以尝试保持打开的连接,直到设备进入挂起模式,关闭连接,然后在设备退出挂起模式时重新建立连接。。。虽然,我个人不喜欢保持一个开放连接的想法。虽然它可以解决这个问题,但我觉得拥有一个开放的c