У меня возникла эта случайная проблема в моем приложении .NET CF, которое использует базу данных SQL Server CE 3.5 SP2.
Когда приложение CF запускается, оно выполняет обслуживание базы данных для проверки .SDF
файла базы данных для проверки с использованием класса Engine
SQL Server CE:
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
библиотеку RAPI через USB. Для правильной работы необходимо включить Active Sync. Настольный компьютер, с которым он взаимодействует, - это Win XP. На некоторых других форумах я видел, что ActiveSync может блокировать файл, что может вызвать проблему. В разделе ActiveSync устройства ничего не выбрано для синхронизации с рабочим столом. Флажок "Файлы" снят. Если у кого-то еще есть предложения о том, как я могу исключить этот файл из ActiveSync, это также будет очень полезно.
ОБНОВЛЕНИЕ. Я использовал 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(); }
Заранее большое спасибо за любую информацию, которую вы можете предоставить.