![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Не ожидать завершения процедуры. [D6, XP]
0?0 © (2012-08-18 08:06:00)Здравствуйте !
Подскажите как запустить процедуру, которая долго работает и не дожидаться её завершения. Т.Е. есть процедура выводящая на печать какие то документы, её нужно запустить и продолжить работу в основном окне программы, а она пусть себе печатает.
O?O (2012-08-24 07:48:00) [1],jkmijt - большое :)
O?O (2012-08-24 07:33:00) [2]Всем ,jkmijt спасибо за советы.
Всё работает, теперь всё ясно и прозрачно!
O?O (2012-08-23 09:28:00) [3]
> Dimka Maslov © (23.08.12 09:08) [20]
Спасибо, попробую разобраться в этом, а то пятой точкой чувствую, что конкурирующие потоки могут натворить бед в том стеке который я создал.
Anatoly Podgoretsky (2012-08-23 09:10:00) [4]> O?O (23.08.2012 08:52:19) [19]
А поиск в файлах не знаком?
Ведь все равно я по памяти не помню, но и проблемы не возникает
Dimka Maslov (2012-08-23 09:08:00) [5]Парметры в поток надо передавать в его конструктор, который проинициализирует все поля объекта до запуска потока.
type
TNewThread = class (TThread)
private
FThreadParam: String; // Тип может быть любой
protected
procedure Execute; override;
public
constructor Create(AThreadParam: String; CreateSuspended: Boolean);
end;
constructor TNewThread.Create(AThreadParam: String; CreateSuspended: Boolean);
begin
FThreadParam := AThreadParam; // присвоили значение поля
inherited Create(CreateSuspended);
end;
procedure TNewThread.Execute;
begin
Спокойно пользуемся FThreadParam;
Не забываем предупредить главную форму об окончании процесса
end;
O?O (2012-08-23 08:52:00) [6]
> Anatoly Podgoretsky © (23.08.12 08:44) [16]
> Можно и так, но некрасиво, лучше CoInitializeEx(NIL,COINIT_MULTITHREADED);
>
Что нужно добавить в uses чтобы эта переменная воспринималась?
O?O (2012-08-23 08:47:00) [7]Может как нибудь подругому параметр передать?
O?O (2012-08-23 08:45:00) [8]И ещё один момент, передача параметров в этот поток.
Сейчас я сделал глобальную переменную для стека:
....
type
....
TMyStack = ^TMyStk;
TMyStk = Record
Next: TMyStack;
Kod: int64;
end;
....
var
....
MyStack: TMyStack;
....
Перед созданием потока в вызывающей процедуре добавляю в стек параметр:
....
var MyStk: TMyStack;
....
new(MyStk);
MyStk^.Next := MyStack;
MyStk^.Kod := ....;
MyStack := MyStk;
MyThread := TMyThread.Create(True);
MyThread.Priority:=tpNormal;
MyThread.FreeOnTerminate := true;
MyThread.Resume;
В потоке делаю так:
....
var MyStk: TMyStack;
MyKod: int64;
....
MyStk := MyStack;
MyStack := MyStk^.Next;
MyKod := MyStk^.Kod;
Dispose(MyStk);
....
....
Anatoly Podgoretsky (2012-08-23 08:44:00) [9]Можно и так, но некрасиво, лучше CoInitializeEx(NIL,COINIT_MULTITHREADED);
O?O (2012-08-23 08:26:00) [10]VCL не использую, но вот этот вызов
CoInitializeEx(NIL, 0);меня смущает, подскажите, грабли есть на которые пока не наступил?
O?O (2012-08-22 15:10:00) [11]Пока поставил так
CoInitializeEx(NIL, 0);
Вроде работает
icWasya (2012-08-22 13:06:00) [12]http://msdn.microsoft.com/en-us/library/windows/desktop/ms695279(v=vs.85).aspx
O?O (2012-08-22 12:17:00) [13]ComObj в Uses имеется, вопрос именно в CoInitialize
O?O (2012-08-22 12:14:00) [14]Создаю поток:
.....
MyThread := TMyThread.Create(True);
MyThread.Priority:=tpNormal;
MyThread.FreeOnTerminate := true;
MyThread.Resume;
exit;
.....
Сам объект:
unit Unit_MyThread;
.....
type
TMyThread = class(TThread)
private
{ Private declarations }
protected
procedure Execute; override;
end;
....
procedure TMyThread.Execute;
var XL: variant;
....
begin
....
XL := CreateOleObject('Excel.Application');
/////////// выполнение этой строки (CreateOleObject) делает ошибку
XL.DisplayAlerts := false;
XL.WorkBooks.Open(Path);
....
В форме вызывающей обьект MyTrhead ни CoInitialize ни CoInitializeEx вызвать неполучается
В обьекте MyThread вроде можно вызвать CoInitializeEx, но непонятно какие параметры ему передать, ничего не воспринимает ещё на уровне компиляции.
Может что специфическое в uses добавить, или ещё чего сделать?
Anatoly Podgoretsky (2012-08-22 11:35:00) [15]
> Собственно вопрос: в какой момент и как его делать?
Перед использованием.
O?O (2012-08-22 10:45:00) [16]делаю.
Запутался чёта :(
O?O (2012-08-22 10:44:00) [17]Вроде всё получается, кроме одного.
Когда программа в потоке хочет создать OLE обьект
XL := CreateOleObject('Excel.Application');
происходит ошибка: "Небыл произведён вызов CoInitialize ...."
Собственно вопрос: в какой момент и как его делать?
В Созданном обьекте MyThread доступент CoInitializeEx, но не воспринимает никакие параметры, или я не то всё делаб
O?O (2012-08-18 19:25:00) [18]Спасибо, буду пробывать.
AV (2012-08-18 11:58:00) [19]проще всего создать новый модуль потока, описать там нужную процедуру, передать ей параметры, запустить поток.
Окончание потока скажет об окончании печати
см. Любая книжка по потокам
например
http://mbo88.narod.ru/ToC.html
O?O (2012-08-18 11:06:00) [20]Процедура выводящая на печать документы уже имеется, возникла проблема ожидания завершения печати. В этом случае для вынесения в отдельный поток нужно изменить параметры этой процедуры или вызывать её другой которая поместит её в отдельный поток, и как это сделать?