System.IO.IOException: процесс не может получить доступ к файлу 'имя_файла' - PullRequest
3 голосов
/ 09 ноября 2010

У меня есть метод в моей службе Windows следующим образом:

System.IO.File.Copy(path, ConfigurationManager.AppSettings["BulkInsertGiftRegisterCreatorDirectory"] + System.IO.Path.GetFileName(path));

Loyalty.Entity.Base.FileInfo file = new Loyalty.Entity.Base.FileInfo();
file.FileName = path;
request.Object = file;

ResponseBase response = new ResponseBase(request);
RequestConnection connection = new RequestConnection("cn");
FileManager fileManager = new FileManager(request, connection);
response = fileManager.OfflineGiftRegisterBulkInsert();

System.IO.File.Delete(ConfigurationManager.AppSettings["BulkInsertGiftRegisterCreatorDirectory"] + System.IO.Path.GetFileName(path));

// here is the part of stored procedure that uses file
SELECT @SCRIPT= 'BULK INSERT GIFT_CARD.GIFT_TEMP'
                            +' FROM '''
                            + @FILE_PATH
                            +''' WITH ('
                                 +'FIELDTERMINATOR = '','','
                                 + 'KEEPNULLS'
                            +');'

Я могу удалить файл из файловой системы вручную, но этот код говорит мне: «Ой! потому что он используется другим процессом. "

Я искал похожие вопросы по stackoverflow и еще где. Но я не мог найти ничего, чтобы помочь мне. Методы копирования или удаления возвращают void, и в моем коде нет потока для удаления.

Как я могу это исправить?

Спасибо заранее.

Ответы [ 3 ]

5 голосов
/ 09 ноября 2010

Вот способ проверить, используется ли файл:

public static System.Boolean FileInUse(System.String file)
{
    try
    {
        if (!System.IO.File.Exists(file)) // The path might also be invalid.
        {
            return false;
        }

        using (System.IO.FileStream stream = new System.IO.FileStream(file, System.IO.FileMode.Open))
        {
            return false;
        }
    }
    catch
    {
        return true;
    }
}

Также, чтобы дождаться файла, который я сделал:

public static void WaitForFile(System.String file)
{
    // While the file is in use...
    while (FileInUse(file)) ; // Do nothing.
}

Надеюсь, это поможет!

4 голосов
/ 09 ноября 2010

Перед просмотром кода вы можете использовать Process Explorer , чтобы определить, какой процесс имеет дескриптор.Это может исключить некоторые проблемы, о которых вы не задумывались

update

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

См. этот вопрос И этот ответ

1 голос
/ 27 мая 2014

Еще лучшее решение - добавить эти две строки кода перед использованием функции FileInUse, которую показал Vercas:

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