Как приостановить выполнение алгоритма программы?
От: AReal  
Дата: 06.06.08 11:23
Оценка:
Здраствуйте!
Подскажите пожалуйста как решить следующую проблему:
я вызываю из delphi внешнюю программу. Она должна выполнить некоторые действия, и в конце сформировать отчёт в файле. Но проблема в том, что она работает долго, и причём,насколько долго — заранее определить невозможно. В моей программе, существует одна из функций, которая должна обратиться к данным файла. Но когда она это делает, то возникает две проблемы:
1. Файл ещё не сформирован полностью
2. Он вообще заблокирован внешней программой
Для решения этих проблем, я решил завести таймер и каждые 100 м.сек обращаться к файлу для проверки его размера. Но при попытке обратится к нему с помощью функции
Reset(f) возникает ошибка. Вобщем не могли бы Вы мне подсказать, каким образом мне можно приостановить алгоритм выполнения моей программы, до тех пор, пока внешняя программа не закончит свою работу и не разблокирует файл?
Re: Как приостановить выполнение алгоритма программы?
От: BlackEric http://black-eric.lj.ru
Дата: 06.06.08 11:26
Оценка: -1
Здравствуйте, AReal, Вы писали:

AR>Здраствуйте!

AR>Подскажите пожалуйста как решить следующую проблему:
AR>я вызываю из delphi внешнюю программу. Она должна выполнить некоторые действия, и в конце сформировать отчёт в файле. Но проблема в том, что она работает долго, и причём,насколько долго — заранее определить невозможно. В моей программе, существует одна из функций, которая должна обратиться к данным файла. Но когда она это делает, то возникает две проблемы:
AR>1. Файл ещё не сформирован полностью
AR>2. Он вообще заблокирован внешней программой
AR>Для решения этих проблем, я решил завести таймер и каждые 100 м.сек обращаться к файлу для проверки его размера. Но при попытке обратится к нему с помощью функции
AR>Reset(f) возникает ошибка. Вобщем не могли бы Вы мне подсказать, каким образом мне можно приостановить алгоритм выполнения моей программы, до тех пор, пока внешняя программа не закончит свою работу и не разблокирует файл?


Ну так и проверяй. Когда ошибка на Reset(f) уйдет — значит работа завершилась.
https://github.com/BlackEric001
Re: Как приостановить выполнение алгоритма программы?
От: Danchik Украина  
Дата: 06.06.08 11:28
Оценка:
Здравствуйте, AReal, Вы писали:

AR>Здраствуйте!

AR>Подскажите пожалуйста как решить следующую проблему:
AR>я вызываю из delphi внешнюю программу. Она должна выполнить некоторые действия, и в конце сформировать отчёт в файле. Но проблема в том, что она работает долго, и причём,насколько долго — заранее определить невозможно. В моей программе, существует одна из функций, которая должна обратиться к данным файла. Но когда она это делает, то возникает две проблемы:

[Skip]

Я так понял програма что то делает, создает файл завершает выполнение. Так?
Как запускаете программу? CreateProcess, ShellExecute, ShellExecuteEx?
Re[2]: Как приостановить выполнение алгоритма программы?
От: Danchik Украина  
Дата: 06.06.08 11:31
Оценка:
Здравствуйте, BlackEric, Вы писали:

[Skip]

BE>Ну так и проверяй. Когда ошибка на Reset(f) уйдет — значит работа завершилась.


И CPU падает в 100%, так? Или Sleep-ов накидаем?
Re[2]: Как приостановить выполнение алгоритма программы?
От: AReal  
Дата: 06.06.08 11:44
Оценка:
Здравствуйте, Danchik, Вы писали:
D>Я так понял програма что то делает, создает файл завершает выполнение. Так?
Да, совершенно верно. Программа проверяет ЭЦП в документах, отчёт о проверке выводит в файл. Мне нужно потом обратиться к этому файлу и определить фамилии сотрудников, ЭЦП которых имеется в этих документах. Сама моя программа запускается переодически, и проверяет на наличие в некоторой папке документов, проверить на ЭЦП которые необходимо. Я ни как не могу определить момента, когда внешняя программа завершила свою работу. Пробовал ставить метки, шо мол, если размер файла не изменился, то вернуться в начало, но толку нет — программа виснит. А в другой раз,решил поставить таймер. Априорно вычислил, что на проверку одного документа уходит примерно 6 сек. после этого внешняя программа выгружается из деспетчера задач, и к файлу который она сформировала, можно спокойно обращаться. Проблема в том, что я не знаю сколько документов предлагается внешней программе для проверки в единицу времени. Потому использовать таймер не имеет смысла. Время так же увеличивается, пичём не линейно, если в файле имеется ЭЦП сразу нескольких сотрудников.


D>Как запускаете программу? CreateProcess, ShellExecute, ShellExecuteEx?

Я использую ShellExecute. Другими вещами я не умею пользоваться.
Re[2]: Как приостановить выполнение алгоритма программы?
От: AReal  
Дата: 06.06.08 11:55
Оценка:
Здравствуйте, BlackEric, Вы писали:
BE>Ну так и проверяй. Когда ошибка на Reset(f) уйдет — значит работа завершилась.
А как мне узнать когда она уйдёт?
Re[3]: Как приостановить выполнение алгоритма программы?
От: BlackEric http://black-eric.lj.ru
Дата: 06.06.08 12:13
Оценка:
Здравствуйте, AReal, Вы писали:

AR>Здравствуйте, BlackEric, Вы писали:

BE>>Ну так и проверяй. Когда ошибка на Reset(f) уйдет — значит работа завершилась.
AR>А как мне узнать когда она уйдёт?

Когда не будет генериться исключение при попытке открытия файла.
https://github.com/BlackEric001
Re[3]: Как приостановить выполнение алгоритма программы?
От: Rius Россия  
Дата: 06.06.08 12:18
Оценка:
Здравствуйте, AReal, Вы писали:

D>>Как запускаете программу? CreateProcess, ShellExecute, ShellExecuteEx?

AR>Я использую ShellExecute. Другими вещами я не умею пользоваться.

Если эта внешняя прога закрывается по завершении, можно просто ждать этого события.
Re[4]: Как приостановить выполнение алгоритма программы?
От: AReal  
Дата: 06.06.08 12:23
Оценка:
Здравствуйте, Rius, Вы писали:

R>Если эта внешняя прога закрывается по завершении, можно просто ждать этого события.

А как ждать? Куда оно должно поступить? Я в этих событиях вообще, к сожалению не шарю.
Re[3]: Как приостановить выполнение алгоритма программы?
От: DarkMaster Украина http://www.bdslib.at.ua
Дата: 06.06.08 12:31
Оценка: -1
Здравствуйте, AReal, Вы писали:

AR>Здравствуйте, Danchik, Вы писали:

D>>Я так понял програма что то делает, создает файл завершает выполнение. Так?
AR>Да, совершенно верно. Программа проверяет ЭЦП в документах, отчёт о проверке выводит в файл. Мне нужно потом обратиться к этому файлу и определить

Ну, можно придумать несколько вариантов и их комбинаций.
1) Сканируем список процессов — одна процедура из jclSysUtils (JEDI). Как только имя процесса ушло из списка — пробуем достучаться к файлу данных...
2) Открываем файл в режиме fmShareDenyNone (для Reset() — читаем о переменной FileMode) и читаем кусками. Как только размер изменился (хоть по таймеру, хоть по эвенту от файловой системы, хоть FindFirst/FindNext проверяем) — читаем следующий кусок. Главное чтобы внешняя прога не открывала файл экслюзивно (fmShareDenyRead).
3) Если нам не удалось доступиться к файлу/прочитать данные — уходим в Sleep(). И пользователю рисуем окошко — мол, работаю.
WBR, Dmitry Beloshistov AKA [-=BDS=-]
Re[5]: Как приостановить выполнение алгоритма программы?
От: Rius Россия  
Дата: 06.06.08 12:38
Оценка:
Здравствуйте, AReal, Вы писали:

AR>Здравствуйте, Rius, Вы писали:


R>>Если эта внешняя прога закрывается по завершении, можно просто ждать этого события.

AR>А как ждать? Куда оно должно поступить? Я в этих событиях вообще, к сожалению не шарю.
Запускаете прогу функцией CreateProcess с параметрами (см. msdn или google) и ждёте пока она вернёт управление. Если ваша прога в это время повисает, попробуйте запускать из другого потока.
Re[5]: Как приостановить выполнение алгоритма программы?
От: Danchik Украина  
Дата: 06.06.08 13:48
Оценка: 5 (2)
Здравствуйте, AReal, Вы писали:

AR>Здравствуйте, Rius, Вы писали:


R>>Если эта внешняя прога закрывается по завершении, можно просто ждать этого события.

AR>А как ждать? Куда оно должно поступить? Я в этих событиях вообще, к сожалению не шарю.

Вот примерчик:
procedure ExecAndWait (FileName : string);
var
  ProcessInfo : TProcessInformation;
  StartupInfo : TStartupInfo;
  ExecString  : string;
begin
  FillChar(StartupInfo, SizeOf(StartupInfo), 0);
  with StartupInfo do begin
    cb := sizeof(StartupInfo);
    lpReserved  := nil;
    lpDesktop   := nil;   {inherit}
    lpTitle     := nil;
    dwFlags     := STARTF_USESHOWWINDOW; {Tis means it should be used wShowWindow}
    wShowWindow := SW_HIDE;
    cbReserved2 := 0;
    lpReserved2 := nil;
  end;

  ExecString := FileName;
  if not CreateProcess( nil,
               PChar(ExecString),
               nil,
               nil,
               false,
               NORMAL_PRIORITY_CLASS,
               nil,
               nil,
               StartupInfo,
               ProcessInfo)
  then 
    RaiseLastOSError;

  case WaitForSingleObject(ProcessInfo.hProcess, 10 * 60 * 1000 {10 min}) of
    WAIT_TIMEOUT : raise Exception.Create ('Process timed out.');
    WAIT_FAILED  : raise Exception.Create ('Process filed')
  end;
end;
Re: Как приостановить выполнение алгоритма программы?
От: CTpaHHoe Россия http://ctpahhoe.blogspot.com/
Дата: 06.06.08 14:35
Оценка:
Здравствуйте, AReal, Вы писали:

AR>Подскажите пожалуйста как решить следующую проблему:

AR>я вызываю из delphi внешнюю программу. Она должна выполнить некоторые действия, и в конце сформировать отчёт в файле. Но проблема в том, что она работает долго, и причём,насколько долго — заранее определить невозможно.

мне неясно, консольное это приложение или GUI.
выложил здесь пример ожидания завершения программы на случай GUI — разбирайся, спрашивай.
test.wait.process.7z

в случае консольного приложения задача еще проще
function StartProcess(const CommandLine : String; ShowFlag : Word) : THandle;
var
  si : TStartupInfo;
  pi : TProcessInformation;
  rc : BOOL;
begin
  FillChar(si, SizeOf(si), 0);
  FillChar(pi, SizeOf(pi), 0);

  si.dwFlags := STARTF_USESHOWWINDOW;
  si.wShowWindow := ShowFlag;


  rc := CreateProcess(nil, PChar(CommandLine), nil, nil, False, 0, nil, nil, si, pi);
  if not rc then
  begin
    Result := 0;
    Exit;
  end;

  CloseHandle(pi.hThread);
  Result := pi.hProcess;  
end;  


...
hProcess := StartProcess('app.exe', SW_SHOWNORMAL);
if (hProcess = 0) then ; // уходим, процесс не запущен
 
dwWait := WaitForSingleObject(hProcess, INFINITE);
CloseHandle(hProcess); // не забываем освобождать хендлы
if (dwWait = WAIT_OBJECT_0) then 
  // успешно дождались
else 
  // какая-то ошибка
... << RSDN@Home 1.2.0 alpha 4 rev. 1089>>
Windows XP 5.1.2600.131072 ... Cannabis Corpse — Addicted to Hash in a Tin
сразу к делу, без приветов. осторожно, злой антиспам
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.