Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.05.27;
Скачать: CL | DM;

Вниз

В отдельном потоке   Найти похожие ветки 

 
Doom-2   (2007-05-10 16:53) [0]

Запускаю несколько процедур подряд в отдельном потоке так:

RunProc([DeleteDirTree("F:\NEW"),
               DeleteDirTree("F:\TEMP"),
                    ExecAndWait(C:\game.exe, SW_SHOWNORMAL),
                         CopyFiles( Handle, dir, "C:\Temp", True, True ),
                           CopyFiles( Handle, dir, "C:\Temp", True, True ),
                              CopyFiles( Handle, dir, "C:\Temp", True, True )],
                                 Otchet);

Использую Unit:
unit ThreadUnit;
interface
uses
 Classes;
type
 TCallArray=array of TThreadMethod;
 TProcCaller = class(TThread)
 private
   { Private declarations }
   CallBackProc:TThreadMethod;
   Procs:TCallArray;
 protected
   procedure Execute; override;
   constructor Create(const AProcs:TCallArray;ACallBackProc:TThreadMethod);
 end;

procedure RunProc(const AProcs:TCallArray;ACallBackProc:TThreadMethod=nil);
implementation
procedure RunProc(const AProcs:TCallArray;ACallBackProc:TThreadMethod=nil);
begin
TProcCaller.Create(AProcs,ACallBackProc);
end;

{ TProcCaller }
constructor TProcCaller.Create(const AProcs:TCallArray;ACallBackProc:TThreadMethod);
begin
 inherited Create(true);
 Procs:=AProcs;
 CallBackProc:=ACallBackProc;  
 Resume;
end;

procedure TProcCaller.Execute;
var i:integer;
begin
for i:=0 to Length(Procs) do begin
 Procs[i];
end;
if Assigned(CallBackProc) then Synchronize(CallBackProc);
Free;
end;

end.

Как исправить ошибки:

[Ошибка] Unit1.pas(437): Incompatible types: "procedure, untyped pointer or untyped parameter" and "Boolean"
[Ошибка] Unit1.pas(438): Incompatible types: "procedure, untyped pointer or untyped parameter" and "Integer"
[Ошибка] Unit1.pas(439): Incompatible types: "procedure, untyped pointer or untyped parameter" and "Integer"
[Ошибка] Unit1.pas(440): Incompatible types: "procedure, untyped pointer or untyped parameter" and "Integer"


 
Doom-2   (2007-05-10 16:56) [1]

Я понимаю, что это из-за:
например, ExecAndWait(C:\game.exe, SW_SHOWNORMAL): boolean;

Неужели придётся переделывать весь код?!


 
iXT ©   (2007-05-10 16:57) [2]

Они в 437 - 440 строках :)


 
Doom-2   (2007-05-10 16:59) [3]

RunProc([DeleteDirTree("F:\NEW"),
              DeleteDirTree("F:\TEMP"),
                   ExecAndWait(C:\game.exe, SW_SHOWNORMAL),            - 437
                        CopyFiles( Handle, dir, "C:\Temp", True, True ),         - 438
                          CopyFiles( Handle, dir, "C:\Temp", True, True ),       - 439
                             CopyFiles( Handle, dir, "C:\Temp", True, True )],   - 440
                                Otchet);


 
clickmaker ©   (2007-05-10 17:05) [4]

в RunProc ты фактически передаешь результаты выполнения функций. Если требуется именно запуск, то указатель на функцию передавай отдельно, ее параметры - отдельно


 
iXT ©   (2007-05-10 17:07) [5]

Ну и.......
RunProc( - какие параметры
и
что возвращают функции в 437-400 ??????

[Ошибка] Unit1.pas(437): Incompatible types: "procedure, untyped pointer or untyped parameter" and "Boolean"
[Ошибка] Unit1.pas(438): Incompatible types: "procedure, untyped pointer or untyped parameter" and "Integer"
[Ошибка] Unit1.pas(439): Incompatible types: "procedure, untyped pointer or untyped parameter" and "Integer"
[Ошибка] Unit1.pas(440): Incompatible types: "procedure, untyped pointer or untyped parameter" and "Integer"

Сдается мне что в качестве параметров нужен указатель, а ты передаешь Bool, Int, Int, Int


 
Doom-2   (2007-05-10 17:09) [6]

clickmaker ©   (10.05.07 17:05) [4]

Подскажи, пожалуйста - как это сделать на примере одной из функций!


 
clickmaker ©   (2007-05-10 17:23) [7]

CopyFilesParams= VarArrayOf([Handle, dir, "C:\Temp", True, True]);
RunProc([CopyFiles, ... ], VarArrayOf([CopyFilesParams, ...]))


 
iXT ©   (2007-05-10 17:33) [8]

"Вы же так не убьетесь"


 
Doom-2   (2007-05-11 10:34) [9]

clickmaker ©   (10.05.07 17:23) [7]

К сожалению, не помогло!
Тут всётаки проблема видимо:
ExecAndWait(C:\game.exe, SW_SHOWNORMAL): boolean;
На те функции, которые без "Result"-а Delphi не ругается

Может, разгадка где-то тут:
iXT ©   (10.05.07 17:07) [5]
что возвращают функции в 437-400 ??????
...
Сдается мне что в качестве параметров нужен указатель, а ты передаешь Bool, Int, Int, Int
!

Тупо убрать ): boolean; нельзя, - он используется в коде самой функции!

Что же тут можно сделать?


 
clickmaker ©   (2007-05-11 10:38) [10]


> [9] Doom-2   (11.05.07 10:34)
> clickmaker ©   (10.05.07 17:23) [7]
>
> К сожалению, не помогло!

а как делал?
задача-то в чем? передать в поток список функций для исполнения?


 
Doom-2   (2007-05-11 11:06) [11]

Как делал?
- и так: ExecAndWaitParams= VarArrayOf([C:\game.exe, SW_SHOWNORMAL]);
- и так: ExecAndWaitParams= VarArrayOf([(C:\game.exe, SW_SHOWNORMAL): true]);
.............. - по всякому!
Да! передать в поток список функций для исполнения
- unit ThreadUnit запускает эти процедуры по порядку в отдельном потоке:

использовать вот так
RunProc([Копирование,Поиск,Архивирование]);
или так, если нужно что то сделать по завершении
RunProc([Копирование,Поиск,Архивирование],МетодЗавершения);


 
clickmaker ©   (2007-05-11 11:33) [12]

 TMyMethod = procedure(const AParams: Variant) of object;

 TCallArray=array of TMyMethod;

 TProcCaller = class(TThread)
 private
  { Private declarations }
  CallBackProc: TThreadMethod;
  Procs: TCallArray;
  Params: Variant;
protected
  procedure Execute; override;
  constructor Create(const AProcs:TCallArray; const AParams: Variant;
       ACallBackProc:TThreadMethod);
end;

procedure TForm1.CopyFiles(const AParams: Variant);
begin
 MessageBox(Handle, PChar(VarToStr(APArams[0])+";"+VarToStr(AParams[1])), "CopyFiles", 0);
end;

procedure TForm1.ExecAndWait(const AParams: Variant);
begin
 MessageBox(Handle, PChar(VarToStr(APArams[0])+";"+VarToStr(AParams[1])), "ExecAndWait", 0);
end;

procedure RunProc(const AProcs:TCallArray; const AParams: Variant; ACallBackProc:TThreadMethod=nil);
begin
 TProcCaller.Create(AProcs,AParams,ACallBackProc);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 ParamArray: Variant;
 Params: Variant;
 Procs: TCallArray;
begin
 ParamArray := VarArrayCreate([0, 1], varVariant);
 Params := VarArrayCreate([0, 1], varVariant);
 Params[0] := "C:\game.exe";
 Params[1] := SW_SHOWNORMAL;
 ParamArray[0] := Params;
 Params := VarArrayCreate([0, 4], varVariant);
 Params[0] := Handle;
 Params[1] := "C:\";
 Params[2] := "D:\";
 Params[3] := True;
 Params[4] := True;
 ParamArray[1] := Params;
 SetLength(Procs, 2);
 Procs[0] := ExecAndWait;
 Procs[1] := CopyFiles;
 RunProc(Procs, ParamArray, nil);
end;

{ TProcCaller }
constructor TProcCaller.Create(const AProcs:TCallArray; const AParams: Variant; ACallBackProc:TThreadMethod);
begin
inherited Create(true);
Procs:=AProcs;
Params := AParams;
CallBackProc:=ACallBackProc;
FreeOnTerminate := true;
Resume;
end;

procedure TProcCaller.Execute;
var i:integer;
begin
for i:=0 to Length(Procs)-1 do begin
  Procs[i](Params[i]);
end;
if Assigned(CallBackProc) then Synchronize(CallBackProc);
end;


 
Doom-2   (2007-05-11 12:06) [13]

На строчках:

Procs[0] := ExecAndWait; - Incompatible types: "procedure, untyped pointer or untyped parameter" and "Boolean"
Procs[1] := CopyFiles;     - Incompatible types: "procedure, untyped pointer or untyped parameter" and "Integer"

8-)           Блин! Что-же делать??????


 
Doom-2   (2007-05-11 12:11) [14]

ExecAndWait(C:\game.exe, SW_SHOWNORMAL): boolean;
CopyFiles( Handle, dir, "C:\Temp", True, True ): integer;
- как это учесть?


 
ЮЮ ©   (2007-05-11 12:26) [15]

>как это учесть?

передавать в RunProc имена процедур(методов) и значения параметров и уже там их выполнять.
Ты же фактически выполняешь эти методы, указав их в качестве фактических параметров, прежде чем вызыввакшь RunProc. Это анвлогично просто

DeleteDirTree("F:\NEW");
DeleteDirTree("F:\TEMP");
ExecAndWait(C:\game.exe, SW_SHOWNORMAL);
...
Otchet;

зачем здксь какой-то  RunProc, если всё и так выполнится до его исполнения?


 
Doom-2   (2007-05-11 12:38) [16]

Мне нужно дождаться завершения процедуры, но чтобы при этом компьютере не зависал!

DeleteDirTree("F:\NEW");
DeleteDirTree("F:\TEMP");
ExecAndWait(C:\game.exe, SW_SHOWNORMAL);


Я так и делаю! Но результатом выполнения ExecAndWait, например является ): boolean; и видимо из-за этого в коде происходит какой-то конфликт?!?!?!


 
iXT ©   (2007-05-11 12:42) [17]

Ни каких конфликтов.

Давай с самого начала, что тебе надо сделать? (Полностью озвучь)


 
Doom-2   (2007-05-11 12:48) [18]

1. Запустить несколько процедур ПОДРЯД (не сразу все скопом)
2. При выполнении данной последовательности процедур программа не подвисала


 
iXT ©   (2007-05-11 12:54) [19]

[15] читал? На какого ты геморой на свою голову создаешь?


 
ЮЮ ©   (2007-05-11 12:57) [20]

>1. Запустить несколько процедур ПОДРЯД (не сразу все скопом)

Обычно код так и выполняется: подряд, строчка за строчкой.

>При выполнении данной последовательности процедур программа не подвисала.

Так она ещё не выполнила одну из процедур. Зачем её быть "не подвисшей"? Чтобы скопом ещё запустить пакат процедур?

ExecAndWait(C:\game.exe, SW_SHOWNORMAL) - а здесь разве по смыслу не требуется именно "завмсвния" до выхода из game.exe?


 
Doom-2   (2007-05-11 12:57) [21]

конкретно
ExecAndWait(C:\game.exe, SW_SHOWNORMAL);
- на время работы game.exe ВИСНЕТ!!!!!!
а знать, когда game.exe закроют мне необходимо!


 
Doom-2   (2007-05-11 13:00) [22]

Хорошо!
Тогда подскажите, пожалуйста:
Как запустить из своей программы внешнее приложение и знать, когда оно завершит свою работу? с программой при этом можно было бы работать (не "завмсвния" до выхода из game.exe)


 
clickmaker ©   (2007-05-11 13:01) [23]


> [16] Doom-2   (11.05.07 12:38)

что ты зациклился? понимаешь разницу между указателем на процедуру и результатом ее выполнения?
Обрати внимание, вот процедура
procedure TForm1.CopyFiles(const AParams: Variant);
а здесь в элемент массива записывается указатель на точку входа в нее
Procs[1] := CopyFiles;

если нужно как-то реагировать на возвращаемое значение, объяви так
TMyMethod = procedure(const AParams: Variant; var Res: Variant) of object;

 TCallArray=array of TMyMethod;

вызов в потоке
for i:=0 to Length(Procs)-1 do begin
  Procs[i](Params[i], Res);
  MessageBox(0, PChar("Result = " + VarToStr(Res)), pchar("Proc "+IntToStr(i)), 0);
end;


 
iXT ©   (2007-05-11 13:09) [24]

> [23] clickmaker ©   (11.05.07 13:01)

Да не нужно ему это все ИМХО. Поэтому и [17] написал :)

game.exe - твоя?


 
clickmaker ©   (2007-05-11 14:10) [25]


> game.exe - твоя?

нет. я только разместил код -)


 
iXT ©   (2007-05-11 14:15) [26]


> [25] clickmaker ©   (11.05.07 14:10)
>
> > game.exe - твоя?
>
> нет. я только разместил код -)

???
Я про это:
ExecAndWait(C:\game.exe, SW_SHOWNORMAL)


 
clickmaker ©   (2007-05-11 14:22) [27]


> [26] iXT ©   (11.05.07 14:15)

так это не ко мне. это к автору


 
iXT ©   (2007-05-11 14:34) [28]

Косяк получился :) Тебе(Вам) была первая строчка :)
Вторая автору


 
Doom-2   (2007-05-11 15:04) [29]

Всё спасибо!
Разобрался!



Страницы: 1 вся ветка

Текущий архив: 2007.05.27;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.103 c
1-1174310573
kodov
2007-03-19 16:22
2007.05.27
Поиск в ListBox


8-1158154178
Lockdog
2006-09-13 17:29
2007.05.27
Определение цвета и преобразование палитры


2-1178621821
RomanLN
2007-05-08 14:57
2007.05.27
как подогнать в компоненте DBGrid1 столбцы по ширине строки


1-1175014811
BigTon
2007-03-27 21:00
2007.05.27
FastReport и StringGrid


2-1178599022
rozik
2007-05-08 08:37
2007.05.27
CheckBox в StringGrid