![]() |
|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
|||
|
|||
![]() Приветствую, господа!
Стоит такая задача: Записать содержимое таблицы в две сторонние БД. Эту задачу необходимо выполнять параллельно - запись в каждую БД в отдельном потоке. Каждый из потоков использует разные компоненты доступа, чтобы не мешать друг другу. Я написал код, который работает, однако как только запускается второй поток, первый становится на паузу и ждет, пока закончится второй. Мне же нужно, чтобы они отработали одновременно. [Класс потока] Код:
Tload = class(TThread) IBDB:TIBDataBase; search:TIBQuery; tsearch,treport:TIBTransaction; import_pre:TIBDataset; import_delete,pre_delete:TIBSQL; memo:Tmemo; public procedure Execute; override; procedure CreareSpec(db:string;memo:tmemo); //определяет в какую БД пишем, и в какой компонент выводим логи end; //тут я динамически создаю компоненты, и их свойста для объекта потока Код:
self.memo:=memo; IBDB:=tibdatabase.Create(form1); ibDB.DatabaseName:=db; Процедура Execute Код:
procedure Tload.Execute; var f:textfile; begin inherited; assignfile(f,'c:\'+memo.Name+'.txt'); rewrite(f); memo.Clear; try каждая операция в цикле записывается в текстовый файл каждая пятитысячная операция (i mod 5000=0) выводится в соотвествующий memo. У каждого объекта потока он точно будет разный. в конце terminate В коде программы объявляю две переменные типа TLoad A1,A2:Tload; и вешаю на две кнопки запуск двух процессов первая кнопка Код:
if ibdb.Connected=false then ibdb.Open; A1:=Tload.Create(true); A1.Priority:=tpNormal; A1.FreeOnTerminate:=true; A1.CreareSpec(db_path1,memo3); A1.Execute; Код:
if ibdb.Connected=false then ibdb.Open; A2:=Tload.Create(true); A2.Priority:=tpNormal; A2.FreeOnTerminate:=true; A2.CreareSpec(db_path2,memo3); A2.Execute; Как я уже говорил, как только я запускаю второй поток, первый становится на паузу. Я почитал литературу, но так и не нашел ответа. Буду рад Вашей помощи. Админ: 2-х дневный бан за несоблюдение правил форума по оформлению кода. Последний раз редактировалось Admin, 04.09.2014 в 19:24. |
#2
|
|||
|
|||
![]() Он именно ожидает? Или вылетает? Если ожидает,то возможно критическая секция
Последний раз редактировалось Heneken, 08.09.2014 в 13:42. |
#3
|
||||
|
||||
![]() А почему я тут не вижу ни одного вызова метода Synchronize()?
|
#4
|
|||
|
|||
![]() Цитата:
|
#5
|
|||
|
|||
![]() только надо не
Код:
A1.Execute; Код:
A1.Resume; |
#6
|
||||
|
||||
![]() Цитата:
Там же обращения к VCL-объектам прямо в Execute()! Маленький копипаст-ликбез из умной книжки: Цитата:
|
#7
|
|||
|
|||
![]() Метод Synchronize нужен только тогда, когда происходит обращение к VCL (и не только к VCL) объектам, находящимся В ГЛАВНОМ ПОТОКЕ ПРИЛОЖЕНИЯ. В данном же случае все компоненты находятся в дополнительном потоке, так что с этим проблем быть не должно.
Я бы грешил на какие-нить объекты синхронизации внутри самих компонентов доступа к БД. Но в таком случае тормозился бы второй поток, т.к. первый уже их занял. Так что тут, видимо, действительно дело в прямом вызове метода Execute, который, вообще-то, должен быть в секции protected, но ТСом перенесен в секцию public, что и позволило вызвать этот метод напрямую в основном потоке приложения, а не создавая дополнительный поток. ТС, поменяй вызов Execute на выов Resume и наступит тебе счастье ![]() |