Ошибка File.Delete «Процесс не может получить доступ к файлу, поскольку он используется другим процессом» - PullRequest
1 голос
/ 06 августа 2010

Я написал набор тестов DotUnit для тестирования некоторых функций импорта данных в моем приложении.Он работает путем создания резервной копии некоторой локальной базы данных Microsoft Access, назовем ее «Test.mdb», «Test.mdb.bak», выполняя некоторый импорт данных (и последующие проверки Assert), а затем восстанавливая оригинал из резервной копии.

Функция SetUp () создает резервную копию, если она не существует.

Функция TearDown () пытается удалить «Test.mdb», а затем скопировать «Test.mdb.bak»to 'Test.mdb'.

Периодическое выполнение тестов завершается с ошибкой «Процесс не может получить доступ к файлу, поскольку он используется другим процессом».

Я посмотрелMSDN для File.Delete и IO разрешений, но не смог найти то, что я был после.Кто-нибудь знает, есть ли функция .NET, которая позволит мне полностью заблокировать файл перед попыткой его удаления?Или найти, какой процесс обращается к нему во время удаления?

Ответы [ 3 ]

7 голосов
/ 06 августа 2010

Вы можете пересмотреть свой подход к тестированию. Вместо этого:

  1. Создать временную копию файла
  2. Выполнение проверяемых действий над временным файлом
  3. Отпустить все дескрипторы (закрыть все соединения) для временного файла
  4. Удалить временный файл

Используя этот шаблон, единственным процессом, который будет обращаться к файлу, будет поток, выполняющий модульное тестирование.

Используйте функцию: System.IO.Path.GetTempFileName();

http://msdn.microsoft.com/en-us/library/system.io.path.gettempfilename.aspx

РЕДАКТИРОВАТЬ: Вот один из способов его кодирования:

var tempFile = System.IO.Path.GetTempFileName();
System.IO.File.Copy(@"C:\Test.mdb", tempFile, true);
// 2. Test tempFile
// 3. Release handles to tempFile, use a using statement around any 
//    streams or System.IO API's that are using the file in any way.
System.IO.File.Delete(tempFile);
6 голосов
/ 16 августа 2013

У меня была похожая проблема при модульном тестировании кода Entity Framework с использованием базы данных SQLite, где каждый тест должен был использовать свежий экземпляр базы данных, поэтому мой метод [TestCleanup] выполнял File.Delete для базы данных, но был получить ту же ошибку «используется другим процессом».

Прежде чем я позвонил в File.Delete, мне пришлось добавить следующее, чтобы исправить мою проблему.

GC.Collect ();

GC.WaitForPendingFinalizers ();

[TestInitialize]
public void MyTestInitialize()
{
    // Copies the embedded resource 'MyDatabase.db' to the Testing Directory
    CommonTestFixture.UnpackFile("MyDatabase.db", this.GetType(), this.TestContext.TestDeploymentDir);
}

[TestCleanup]
public void MyTestCleanup()
{
    // Adding the following two lines of code fixed the issue
    GC.Collect();
    GC.WaitForPendingFinalizers();

    // Removes 'MyDatabase.db' from the testing directory.
    File.Delete(Path.Combine(this.TestContext.TestDeploymentDir, "MyDatabase.db"));
}

[TestMethod]
public void GetVenueTest()
{
    // CreateTestEntities() is a helper that initializes my entity framework DbContext
    // with the correct connection string for the testing database.
    using (var entityFrameworkContext = CreateTestEntities())
    {
        // Do whatever testing you want here:
        bool result = entityFrameworkContext.TestSomething()
        Assert.IsTrue(result);
    }
}
2 голосов
/ 14 мая 2015

Эти две строки решают проблему.

GC.Collect();
GC.WaitForPendingFinalizers();

Я проверил это в своем коде, и оно работало хорошо.

--- Джитендра

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...