Форум: "Основная";
Текущий архив: 2004.08.01;
Скачать: [xml.tar.bz2];
ВнизОтчет в Word в отдельном потоке Thread Найти похожие ветки
← →
Виталя © (2004-07-15 14:12) [0]Я пытаюсь "отвести" создание отчета в Wordе(при помощи OLE) в отдельный поток, так чтобы пользователь мог работать с программой пока он формируется.
TWordThread = class(TThread)
private
fWF:WordFuncs;
//это мой класс в нем хранятся настройки для Word и процедуры вывода отчетов (вполне рабочие)
fIBQ:TIBQuery;
protected
procedure Execute; override;
public
constructor Create(AWF:WordFuncs;AIBQ:TIBQuery);
end;
implementation
constructor TWordThread.Create(AWF:WordFuncs;AIBQ:TIBQuery);
begin
inherited Create(true);
fWF:=aWF;
fIBQ:=AIBQ;
Resume;
end;
procedure TWordThread.Execute;
begin
fWF.SaveQueryToWord(fIBQ);//эта процедура откр.Word, создает новый документ , в нем табл. и заполняет ее инф. из Query
fWF.Done;
fIBQ.Transaction.Commit;
Destroy;//После вывода данных поток уничтожается
end;
В теле программы я опред. переменную
WordThread:TWordThread;
и создаю поток
WordThread:=TWordThread.Create(WF,IBQ_);
Word открывается, но документ не создается - выдается ошибка класса EOleSysError с сообщ "CoInitialize has not been called".
Может нельзя использовать Tread для таких целей(я его вообще-то первый раз использую). Помогите разобраться пожалуйста.
← →
Суслик (2004-07-15 14:14) [1]
> CoInitialize has not been called
вам пересвести?
"CoInitialize не был вызван"
Значит что?
Надо вызвать?
Точно.
Первой строчкой execute поставте coinitialize(не помню праметров)
Такой вызов нужно делать для каждого потока - в главном за вас дельфи уже это сделал. В доппотоках - делайте сами.
← →
Суслик (2004-07-15 14:15) [2]и еще сомневаюсь, что word переварит многопоточный доступ к себе.
← →
Виталя © (2004-07-15 15:22) [3]а вы не подскажите в каком модуле описана эта ф-ция, а то у меня Delphi ее не узнает, хотя ComObj в список включен, а в хелпе на эту функцию модуль не указан.
← →
clickmaker © (2004-07-15 15:27) [4]
> Виталя © (15.07.04 15:22) [3]
> а вы не подскажите в каком модуле описана эта ф-ция
ActiveX
← →
Суслик (2004-07-15 15:31) [5]
> Виталя © (15.07.04 15:22) [3]
понятия не имею, но total comander + alt f7 в диркетории с исходниками отвечают на все вопросы.
← →
Sha © (2004-07-15 15:40) [6]Виталя © (15.07.04 14:12)
И еще.
Идеологически неверно писать Resume в конструкторе потока, да и не вседа безопасно к тому же.
В твоем случае лучше вызыватьinherited Create(false);
← →
Виталя © (2004-07-15 15:43) [7]спасибо,
хотя теперь оно говорит, что приложение вызвало интерфейс, маршалированный для другого потока...
← →
Суслик (2004-07-15 15:46) [8]
>
> Виталя © (15.07.04 15:43) [7]
> спасибо,
> хотя теперь оно говорит, что приложение вызвало интерфейс,
> маршалированный для другого потока...
вот я про это и говорил - не все ком сервера позволяют так себя насиловать. Создавай объект (т.е. CreateOleObject) прямо в потоке - в функции exeсute. Проблем не будет.
> Sha © (15.07.04 15:40) [6]
Александр, почему?
Вроде все нормально
← →
Sha © (2004-07-15 15:50) [9]Суслик (15.07.04 15:46) [8]
AfterConstruction проверяет CreateSuspended(или как-то так), и если оно false, то делает Resume. Проверка приводит к AV, если поток успеет закончить вычисления к этому времени. Вполне реальная ситуация.
← →
Суслик (2004-07-15 15:54) [10]
> Sha © (15.07.04 15:50) [9]
Вы что-то путаете.
У нее (автора) же CreateSuspended = true.
← →
Sha © (2004-07-15 15:55) [11]Суслик (15.07.04 15:54) [10]
Но проверка-то выполняется всегда.
← →
Суслик (2004-07-15 15:58) [12]
> Sha © (15.07.04 15:55) [11]
> Суслик (15.07.04 15:54) [10]
>
> Но проверка-то выполняется всегда.
И?
FreeOnTerminate равно false.
Поэтому к моменту отработки указанной вами проверки с объектом ничего не случится - ни в случае, если поток уже закончит работу, ни в случае если еще будет продолжнать. Проверка даст false и никакого resume не будет.
← →
Виталя © (2004-07-15 15:59) [13]насчет идеологии не знаю, а конструкция из статьи на этом форуме, хотя похоже код
constructor TWordThread.Create(AWF:WordFuncs;AIBQ:TIBQuery);
begin
fWF:=aWF;
fIBQ:=AIBQ;
inherited Create(false);
end;
будет эквивалентен.
> Суслик (15.07.04 15:46) [8]
> вот я про это и говорил - не все ком сервера позволяют так
> себя насиловать. Создавай объект (т.е. CreateOleObject)
> прямо в потоке - в функции exeсute. Проблем не будет.
Действительно получилось, спасибо.
← →
Суслик (2004-07-15 16:01) [14]
> Действительно получилось, спасибо.
Спасибо, буду знать, т.к. советовал я исключительно по книгам - не по опыту.
← →
Sha © (2004-07-15 16:01) [15]Суслик (15.07.04 15:58) [12]
Естественно AV будет только при FreeOnTerminate = true. Именно поэтому я и написал, что
Идеологически неверно писать Resume в конструкторе потока, да и не всегда безопасно к тому же.
← →
Суслик (2004-07-15 16:12) [16]Идеология - штука сложная.
Я вообще не пользуюсь FreeOnTerminate, поэтому мне (как и примеру кода автора) такое не грозит.
← →
Sha © (2004-07-15 16:12) [17]> Виталя © (15.07.04 15:59) [13]
Нет никакой необходимости вызывать inherited конструктор после операторов присваивания, можно писать как обычно:constructor TWordThread.Create(AWF:WordFuncs;AIBQ:TIBQuery);
begin
inherited Create(false);
fWF:=aWF;
fIBQ:=AIBQ;
end;
← →
Sha © (2004-07-15 16:15) [18]Суслик (15.07.04 16:12) [16]
У меня наоборот, почти всегда FreeOnTerminate = true,
и на вызове Resume из конструктора, было дело, обжигался.
← →
Суслик (2004-07-15 16:19) [19]
> Sha © (15.07.04 16:15) [18]
Согласен, наверное (внимаетльно не смотрел).
Я вообще перестал пользоваться tthread :)))
CreateThread и дело с концом.
← →
Sha © (2004-07-15 16:22) [20]Суслик (15.07.04 16:19) [19]
Это да, но часто удобно пользоваться методами.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2004.08.01;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.04 c