Форум программистов, компьютерный форум, киберфорум
Наши страницы
C# .NET
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.75/4: Рейтинг темы: голосов - 4, средняя оценка - 4.75
igordev
0 / 0 / 0
Регистрация: 23.01.2014
Сообщений: 4
1

Копирование файла на место удаленного. Ошибка "Файл занят"

23.01.2014, 16:37. Просмотров 819. Ответов 7
Метки нет (Все метки)

Столкнулся с очень своеобразной проблемой. В цикле постоянно копируется и запускается консольная программа, их около 200 разных, но всегда копирую с именем a.exe, запускаю с разными параметрами, может все нормально работать день и два, но начинаю немного машину подгружать и выскакивают исключения типа "файл занят"... тупо поставил цикл с паузой на удаление и на копирование, если попытка провалилась, все заработало, но это очень некрасиво и несовсем понятно, может кто посоветует куда смотреть. Самое странное, что даже иногда файл удаляется с первого захода, а на его место копируется другой с таким-же именем, то тоже может исключение вылететь на копировании(после успешного удаления!!!). Если в компе нет других активных процессов, то все работает с первых-же проходов, проблема только когда загружаю CPU и память внешними программами, т.е. беру IE и полезл активно в инет уже вносит нестабильность. 2я попытка после паузы 500мс срабатывает нормально, до 3й еще не смог загрузить...
Пробовал на разных машинах на Win 2003 Server, Windows 7 proff, Windows 8

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
myProcess = new Process();
myProcess.StartInfo.UseShellExecute = false;
myProcess.StartInfo.FileName = SCParameters.WorkDir + "\\a.exe";
myProcess.StartInfo.Arguments = task.InputFile + " " + task.OutputFile + " ans.txt checker.res -appes";
myProcess.StartInfo.CreateNoWindow = !bConsole;
myProcess.StartInfo.WorkingDirectory = SCParameters.WorkDir;
myProcess.Start();
myProcess.WaitForExit();
myProcess.Close();
 
 
if (File.Exists(SCParameters.WorkDir + "\\a.exe"))
{
    for (int i = 0; i < 3; i++)
    {
        try
         {
             File.Delete(SCParameters.WorkDir + "\\a.exe");
             break;
         }
         catch
         {
             SCMsgError("Попытка " + i + " из 3 удалить файл провалилась...");
             Thread.Sleep(500);
         }
     }
}
 
for (int i = 0; i < 3; i++)
{
     try
     {
           File.Copy(SCParameters.WorkDir + "\\Tasks\\a.exe", SCParameters.WorkDir + "\\a.exe", true);
           break;
     }
     catch
     {
           SCMsgError("Попытка копирования " + i + " из 3 провалилась...");
           Thread.Sleep(500);
     }
}
0
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
23.01.2014, 16:37
Ответы с готовыми решениями:

Синхронизация файлов в двух папках. При работе с большими файлами возникает ошибка "Файл занят другим процессом"
Доброго времени суток. У меня такой вопрос. Пишу программу для синхронизации данных в двух...

Копирование файла типа "файл"
Привет, у меня проблема, есть файлы типа &quot;файл&quot; и задача скопировать их в другую папку, но Visual...

"Сплошное" копирование и переименование файла
Всем привет. Существует задача по перемещению (с оговорками) группы файлов из одного расположения в...

Ошибка после конвертации метода на С++ к С#: "Неявное преобразование типа "int" в "bool" невозможно"
Ошибка после преобразования метода на С++ к С#: &quot;Неявное преобразование типа &quot;int&quot; в &quot;bool&quot;...

Ошибка CS0019: Оператор "*" не может применяться к операндам типа "decimal" и "float"
Здравствуйте! Писал приложение и наткнулся на интересную ошибку (честно говоря, я не совсем понимаю...

7
НеСказочник
58 / 46 / 13
Регистрация: 12.11.2012
Сообщений: 367
Записей в блоге: 2
28.01.2014, 22:14 2
А у вас значит на место файла копируется ещё один, даже если все три попытки удалить провалились?
И ещё, переведённый выше код исполняется единожды или повторяется.
0
nio
5990 / 3397 / 335
Регистрация: 14.06.2009
Сообщений: 8,136
Записей в блоге: 2
28.01.2014, 23:48 3
ересь какая-то: 200 различных программ переименовываются в "a.exe". Зачем?
Кажется мне, что тут какой-то затык с проектированием....
0
igordev
0 / 0 / 0
Регистрация: 23.01.2014
Сообщений: 4
29.01.2014, 07:21  [ТС] 4
Цитата Сообщение от НеСказочник Посмотреть сообщение
А у вас значит на место файла копируется ещё один, даже если все три попытки удалить провалились?
И ещё, переведённый выше код исполняется единожды или повторяется.
Обычно если первая попытка провалилась, то вторая попытка успешная, до третей никогда дело не доходит. Т.е. удаление происходит всегда. С копированием та-же история, если первая провалилась, то вторая проходит.

Добавлено через 12 минут
Приведенный код работает 20-50 раз подряд.

Добавлено через 7 минут
Цитата Сообщение от nio Посмотреть сообщение
ересь какая-то: 200 различных программ переименовываются в "a.exe". Зачем?
Кажется мне, что тут какой-то затык с проектированием....
Это система проверки олимпиадного программирования. Для каждого посланного решения, его надо запустить 20-50 раз с разными файлами данных (тестов), а потом программа a.exe (проверялка предоставляемая жюри) читает выходные данные программы участника и делает проверку правильности ответов. Т.е. все запускается 20-50 раз, разные только файлы данных с которыми они работают. Так для каждой посылки, количество посылок во время турнира около 200. Пример подобной системы вот http://a c m p.r u/article.asp?id_text=120
0
29.01.2014, 07:21
НеСказочник
58 / 46 / 13
Регистрация: 12.11.2012
Сообщений: 367
Записей в блоге: 2
29.01.2014, 12:04 5
А ведь можно же сложить их всех в одну папку, узнать сколько в этой папке экзешников (сейчас так не вспомню, но это точно можно программно) и запускать разные экзешники, каждый под своим именем. Почему не так?
0
igordev
0 / 0 / 0
Регистрация: 23.01.2014
Сообщений: 4
29.01.2014, 13:08  [ТС] 6
Цитата Сообщение от НеСказочник Посмотреть сообщение
А ведь можно же сложить их всех в одну папку, узнать сколько в этой папке экзешников (сейчас так не вспомню, но это точно можно программно) и запускать разные экзешники, каждый под своим именем. Почему не так?
Можно конечно, копировать под уникалиным GUID и запускать, проблема изчезнет, но это булочка, которая латает изъян логики Windows, т.е. получается, что WaitForExit редко, но иногда не точно отрабатывается. Я перелапатил кучу форумов и понял, что подобная проблема не только у меня, объяснения сводятся к подобному:
> According to my experiences when the process handle becomes signaled
> (terminates) it's likely (especially on multi-processor/core systems) that
> file handles are still open. This may be the side effect of the fact that
> handles live in kernel-mode and the cleanup is done after the process
> handle is signaled.
>
> You either can either use FILE_FLAG_DELETE_ON_CLOSE and share the handle
> or if you can't use that you should sleep for example 200 or 500 ms and
> try to delete again. You also should do this when this specific error code
> or exception appears because other error codes most likely indicate error
> conditions that cannot be solved by a loop
Оставил пока как есть, срабатывает в основном с первого раза и очень редко если с первой попытки не прошло, достаточно паузы 50мс и повтор нормально проходит, но это так каряво...
Вот тут нашел подобное http://social.msdn.microsoft.com/For...ompletely-exit
0
nio
5990 / 3397 / 335
Регистрация: 14.06.2009
Сообщений: 8,136
Записей в блоге: 2
29.01.2014, 23:57 7
igordev, ты не понял. Всё гораздо проще: файлы для тестирования складываются в одну папку, нехитрым способом можно получить их имена в массив, и дальше в цикле запускаешь процессы с нужной командной строкой. При этом не нужно ждать освобождения файла, не нужно производить переименование, при достаточно мощной машине можно тестировать сразу несколько программ одновременно...
0
igordev
0 / 0 / 0
Регистрация: 23.01.2014
Сообщений: 4
30.01.2014, 07:47  [ТС] 8
nio,
Да нет, ты не совсем представляешь что такое олимпиадное программирование. У запускаемого процесса надо контролировать сколько он занимает памяти, в случае превышения лимита убивать его и прописывать в базу "Ошибка по лимиту памяти", контролировать время выполнения и в случае превышения убивать процесс, причем время выполнения 2х одновременных программ и одной программы на 4х процессорной машине не совсем линейно, т.е. если одна программа выполняется 2 секунды, то теоретически 2 программы на 4х процессорах тоже должны в районе 2 сек выполняться, но в реале они работают 1.5-1.8 секунд и время плавает и достаточно непредсказуемо плавает. Т.е. никакого распараллеливания и жесткий контроль памяти и времени выполнения. Ну а самое главное, участникам зачастую проще ломать систему, чем решать задачу и они в этом очень неплохо преуспевают)))
0
30.01.2014, 07:47
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
30.01.2014, 07:47

Ошибка: "Не удалось привести тип объекта "System.ConsoleKeyInfo" к типу "System.IConvertible"."
При запуске пишет, что &quot;Не удалось привести тип объекта &quot;System.ConsoleKeyInfo&quot; к типу...

"Вшить" в файл имя файла. Или как из string перевести в byte[]
Здравствуйте. Считываю файл, получаю массив байтов. Сохраняю его имя, расширение, хеш в переменные....

Текстовый файл. строка с 3 "объектами" разделенные разделителем "," как обратиться к каждому из объектов?
Всем добрый день. Имеется текстовый файл. содержимое: более 31.000 строк. каждая строка...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.