Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.119.133.228] |
|
Сообщ.
#1
,
|
|
|
Думал, что можно избавиться от зависания при ожидании завершения программы запущенной CreateProcess путем выполнения этой команды(CreateProcess и WaitforSingleObject) в созданном специально для этого потоке, как я это делаю для Socket'ов. Но приложение все равно ждет (т.е. не откликается).
Один поток работает с сетью и периодически архивирует полученные данные. Из этого потока я создаю поток архивации, а там вызываю Rar и жду его завершения. Rar запускается, а моя программа наоборот, подвисает... Можно эту проблему решить? СУВ. procedure Execute; override; procedure TArchThread.Execute; begin inherited; if Main.ArcIPsList.IndexOf(FRemoteClientIP)<>-1 then begin Main.ArcIPsList.Append(FRemoteClientIP); end; Synchronize(PackFiles); Destroy; end; procedure TArchThread.PackFiles; procedure RarFile(ArcName, FileName: string); var WinRarPath: string; Reg_: TRegistry; s: string; Rlst: LongBool; StartUpInfo: TStartUpInfo; ProcessInfo: TProcessInformation; ExitCode: Cardinal; begin Reg_:=TRegistry.Create; Reg_.RootKey:=HKEY_LOCAL_MACHINE; Reg_.OpenKey('SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\WinRAR.exe',False); WinRarPath :=Reg_.ReadString('Path'); FillChar(StartUpInfo, SizeOf(TStartUpInfo), 0); with StartUpInfo do begin cb := SizeOf(TStartUpInfo); dwFlags := STARTF_USESHOWWINDOW or STARTF_FORCEONFEEDBACK; wShowWindow := SW_SHOWNORMAL; end; s := ' a -as ' + ArcName + ' '+ FileName; Rlst := CreateProcess(nil , PChar(WinRarPath+'\winrar.exe'+s) , nil, nil, false, NORMAL_PRIORITY_CLASS, nil, nil, StartUpInfo, ProcessInfo); if Rlst then begin with ProcessInfo do begin if WaitforSingleObject(ProcessInfo.hProcess, INFINITE)<>0 do begin // Application.ProcessMessages; end; CloseHandle(hThread); CloseHandle(hProcess); end end; Reg_.Free end; begin RarFile(FArchFileName,FFileName); end; |
Сообщ.
#2
,
|
|
|
Вообщето у тебя написано Synchronize(PackFiles);. А это значит что ты просишь выполниться PackFiles в контексте ОСНОВНОГО (VCL) ПОТОКА. Т.е. пока выполняется PackFiles вся интерактивная деятельность программы заморожена.
Synchronize нужно использовать только для вызова методов которые используют методы и свойства VCL, поскольку VCL не реентерабельна (потоконебезопасна). Поскольку у тебя в PackFiles вроде-бы нет вызовов VCL, то и не надо ее вызывать через Synchronize. P.S. В свое время, кажется на "Мастерах Delphi", я встретил статью о том как писать многопоточные приложения. Так вот, там автор приводил именно такой метод - всю работу потока разместить в одном методе, и вызывать его из Execute через Syncronize. Я бы этому автору руки поотрывал бы, что-бы не учил людей тому, чего сам делать не умеет! |
Сообщ.
#3
,
|
|
|
Это заработало...
Мерси, на VITаминовском форуме вопросик есть еще СУВ. |