Форум: "Начинающим";
Текущий архив: 2006.11.26;
Скачать: [xml.tar.bz2];
ВнизОшибка в выполнении параллельного потока Найти похожие ветки
← →
ГореПрограммер (2006-11-07 12:51) [0]Здравствуйте.
есть клас:
Tloadfon = class(TThread)
protected
procedure sinform;
procedure Execute; override;
end;
procedure tloadfon.sinform;
begin
fstart.prog1.StepIt;
end;
procedure tloadfon.Execute;
var i:integer;
begin
FreeOnTerminate := True;
for i := 0 to ar_excel.count - 1 do
begin
if Terminated then
Break;
loadip(ar_excel.zaps[i].mac,i);
getminup(ar_excel.zaps[i].id);
Synchronize(sinform);
end;
end;
В момент обращения к нему, т.е.
tloadfon.create(false);
выдается ошибка базы данных:
dbExpress Error: Unknown Error Code "256"
[0x0005]: Operation Not Supported
Database Server Error: Failed to query the server.(Error "2013"; Reason "Lost connection to MySQL server during query")
если выполнять функции loadip и getminup не в этом потоке, а просто в программе, то никаких ошибок не происходит. Подскажите пожалуйста где искать ошибку ?
← →
ГореПрограммер (2006-11-07 12:54) [1]Да, если это имеет значение,
procedure loadip(mac:string;ind:integer);
fproc.q2.Active:=false;
fproc.q2.SQL.Clear;
fproc.q2.SQL.Add("select ip from ip_addr where mac_term="""+mac+"""");
fproc.q2.Active:=true;
после активации запроса вылетает как раз ошибка. и как я выше писал вылетает ошибка только при попытке сделать это в параллельном потоке
← →
DVM © (2006-11-07 12:58) [2]
> ГореПрограммер (07.11.06 12:51)
> ar_excel
Это чаво такое и почему обращение к этой переменной может быть безопасным?
> loadip(ar_excel.zaps[i].mac,i);
> getminup(ar_excel.zaps[i].id);
Это чаво?
← →
MetalFan © (2006-11-07 13:01) [3]что есть fproc?
ты из потока к VCL компонентам лезешь...
создавай q2 в потоке)
← →
ГореПрограммер (2006-11-07 13:02) [4]
> > ar_excel
массив записей (record)
> > loadip(ar_excel.zaps[i].mac,i);
> > getminup(ar_excel.zaps[i].id);procedure loadip(mac:string;ind:integer);
var i,j:integer;
begin
strex:=strex+"loadip";
fproc.q2.Active:=false;
fproc.q2.SQL.Clear;
fproc.q2.SQL.Add("select ip from ip_addr where mac_term="""+mac+"""");
fproc.q2.Active:=true;
......
function getminup(id:string):string;
begin
fproc.q2.Active:=false;
fproc.q2.SQL.Clear;
fproc.q2.SQL.Add("select min(date_up) from Jurup where Term_id="+id);
fproc.q2.Active:=true;
.....
← →
ГореПрограммер (2006-11-07 13:03) [5]
> что есть fproc?
> ты из потока к VCL компонентам лезешь...
> создавай q2 в потоке)
fproc это модуль, в котором содержится q2.
Поток создается в другом модуле
← →
DVM © (2006-11-07 13:05) [6]
> массив записей (record)
Этот массив кем-то чем-то может быть изменен во время отработки потока?
Если да - будут глюки.
> loadip(ar_excel.zaps[i].mac,i);
> getminup(ar_excel.zaps[i].id);
Убирай в Synchronize()
← →
MetalFan © (2006-11-07 13:16) [7]
> DVM © (07.11.06 13:05) [6]
>
> Убирай в Synchronize()
... и смысл вынесения в поток теряется)
← →
ГореПрограммер (2006-11-07 13:18) [8]
> > loadip(ar_excel.zaps[i].mac,i);
> > getminup(ar_excel.zaps[i].id);
>
> Убирай в Synchronize()
Спасибо, все заработало.
Вот только второй вопрос. Мне необходимо чтобы
> procedure tloadfon.Execute;
выполнилась только один раз. Каким образом её следует переписать, чтобы после прохождения цикла поток прекратил свою работу ?
пробовал так:
> procedure tloadfon.sinform;
> begin
> fstart.prog1.StepIt;
> end;
> procedure tloadfon.Execute;
> var i:integer;
> begin
> FreeOnTerminate := True;
> for i := 0 to ar_excel.count - 1 do
> begin
> if Terminated then
> Break;
> loadip(ar_excel.zaps[i].mac,i);
> getminup(ar_excel.zaps[i].id);
> Synchronize(sinform);
> end;
> terminate;
> end;
не помогло, все равно цикл выполняется еще раз
← →
Сергей М. © (2006-11-07 13:24) [9]
> Мне необходимо чтобы
> > procedure tloadfon.Execute;
>
> выполнилась только один раз
Он (этот метод) всего один раз и выполнится, вне зависимости от того что у него в "потрохах"
← →
Anatoly Podgoretsky © (2006-11-07 13:25) [10]
> и смысл вынесения в поток теряется)
А здесь он появляется в проявлении ошибки, и разница то? Небольшая, лучше пусть работает, чем не работает. Может и потоки не нужны.
← →
ГореПрограммер (2006-11-07 13:26) [11]Да, но в этом случае вопрос. каким образом после однократного прохождения цикла внутри метода поток "исчезал" ?
← →
MetalFan © (2006-11-07 13:28) [12]а нафиг в execute terminate вызывается??
почитай про потоки плз сначала, а потом тут ахинею городи.
неплохая статья, имхо
http://forum.vingrad.ru/topic-60076.html
← →
DVM © (2006-11-07 13:29) [13]
> однократного прохождения цикла
один оборот цикла? Убрать цикл :)
FreeOnTerminate := True;
после отработки Execute он уничтожится.
← →
Anatoly Podgoretsky © (2006-11-07 13:30) [14]Он и исчезает и ненужный, лишний вызов метода Terminate
← →
ГореПрограммер (2006-11-07 13:31) [15]
procedure tloadfon.sinform;
begin
loadip(ar_excel.zaps[index].mac,index);
getminup(ar_excel.zaps[index].id);
fstart.prog1.StepIt;
end;
procedure tloadfon.Execute;
var i:integer;
begin
FreeOnTerminate := True;
for i := 0 to ar_excel.count - 1 do
begin
if Terminated then
Break;
index:=i;
Synchronize(sinform);
end;
end;
В execute цикл проходит один раз, потом начинает заново.
← →
ГореПрограммер (2006-11-07 13:34) [16]Пробовал так:
> procedure tloadfon.Execute;
> var i:integer;
> begin
> FreeOnTerminate := True;
> for i := 0 to ar_excel.count - 1 do
> begin
> if Terminated then
> Break;
> index:=i;
> Synchronize(sinform);
> end;
> showmessage("test");
> end;
showmessage не срабатывает. заканчивается цикл, тишина и потом цикла начинается заново.
← →
DVM © (2006-11-07 13:34) [17]
> index:=i;
Это что еще? Почему меняешь из потока так смело значения переменных?
← →
ГореПрограммер (2006-11-07 13:36) [18]
> > index:=i;
>
> Это что еще? Почему меняешь из потока так смело значения
> переменных?
Извиняюсь, это я убрал уже. Результат тот же (
← →
DVM © (2006-11-07 13:41) [19]И все же ar_excel меняется в основном потоке или нет? Лучше создай у объекта потока поле FCount и свойство Count с доступом через критическую секцию. Так понадежнее. Хотя к количеству повторов цикла отношения это вряд ли имеет.
← →
Anatoly Podgoretsky © (2006-11-07 13:45) [20]
> showmessage не срабатывает. заканчивается цикл, тишина и
> потом цикла начинается заново.
Происходит исключение, тихое.
← →
Сергей М. © (2006-11-07 13:46) [21]
> showmessage не срабатывает
Его обязательно следует синхронизировать с осн.потоком.
> потом цикла начинается заново.
С чего ты взял ?
← →
ГореПрограммер (2006-11-07 13:48) [22]
> > showmessage не срабатывает. заканчивается цикл, тишина
> и
> > потом цикла начинается заново.
>
> Происходит исключение, тихое.
А каким образом диагностировать где и какая ошибка ?
← →
ГореПрограммер (2006-11-07 13:50) [23]
> > потом цикла начинается заново.
>
>
> С чего ты взял ?procedure tloadfon.sinform;
begin
loadip(ar_excel.zaps[index].mac,index);
getminup(ar_excel.zaps[index].id);
fstart.prog1.StepIt;
end;
procedure tloadfon.Execute;
var i:integer;
begin
FreeOnTerminate := True;
for i := 0 to ar_excel.count - 1 do
begin
if Terminated then
Break;
index:=i;
Synchronize(sinform);
end;
fstart.prog1.Position:=0;
fstart.stat.Panels[0].Text:="Все данные загружены";
end;
После окончания заполнения прогресбара. через секунлы 2 он опять начинает заполняться. Логично что еще раз срабатывает цикл
← →
DVM © (2006-11-07 13:52) [24]Поставь windows.beep(500,50); в цикл
← →
Сергей М. © (2006-11-07 13:54) [25]Потому что процедура sinform() (в которой твой прогрессбар заполняется) у тебя вызывается ar_excel.count раз
← →
ГореПрограммер (2006-11-07 14:04) [26]
> Потому что процедура sinform() (в которой твой прогрессбар
> заполняется) у тебя вызывается ar_excel.count раз
логично. мне и необходимо её выполнить ar_excel.count раз. Но после выполнения её ar_excel.count раз она выполняется опять столько же и так до бесконечности
← →
DVM © (2006-11-07 14:07) [27]
> ГореПрограммер (07.11.06 14:04) [26]
ты бип в цикл поставил? цикл работает?
← →
ГореПрограммер (2006-11-07 14:08) [28]
> > ГореПрограммер (07.11.06 14:04) [26]
>
> ты бип в цикл поставил? цикл работает?
Да, все тоже самое. цикл работает. и после окончания выполняется еще и еще
← →
DVM © (2006-11-07 14:12) [29]вообще странно, не должно быть если поток заново кто-то не создает.
поставь еще if Terminated then exit; вместо break;
← →
ГореПрограммер (2006-11-07 14:19) [30]Поставил. ситуация таже( вызывает create один раз, после строки создания потока поставил showmessage сообщение появляется только один раз
← →
Сергей М. © (2006-11-07 14:25) [31]Отладчиком умеешь пользоваться ?
← →
ГореПрограммер (2006-11-07 14:30) [32]
> Сергей М. © (07.11.06 14:25) [31]
Если ставлю точку остановки на следующую строку после цикла то процесс выполнения не прерывается
← →
Anatoly Podgoretsky © (2006-11-07 14:39) [33]
> if Terminated then exit; вместо break
Смысла нет, масло масляное
← →
Сергей М. © (2006-11-07 14:42) [34]
> fstart.prog1.Position:=0; // <--- сюда ставишь ?
> fstart.stat.Panels[0].Text:="Все данные загружены";
← →
ГореПрограммер (2006-11-07 14:47) [35]Да, именно сюда
← →
Anatoly Podgoretsky © (2006-11-07 14:50) [36]> ГореПрограммер (07.11.2006 14:19:30) [30]
Но ты же именно это и просил, чем теперь недоволен?
← →
Сергей М. © (2006-11-07 14:55) [37]
> FreeOnTerminate := True;
> for i := 0 to ar_excel.count - 1 do //<-- ставь брейкпойнт сюда и - вперед с песней, пошагово, с контролем происходящего после каждого шага
← →
ГореПрограммер (2006-11-07 15:01) [38]
>
> Но ты же именно это и просил, чем теперь недоволен?
Я хотел чтобы цикл выполнился один раз, а не бесконечное число раз
← →
Сергей М. © (2006-11-07 15:03) [39]
> хотел чтобы цикл выполнился один раз, а не бесконечное число
> раз
>
Он и будет выполняться столько раз, сколько ему тобой предписано. Если найдешь и устранишь ошибки. Собственно к данному потоку это не имеет ни малейшего отношения - то же самое можно "накосячить" в любом ином потоке, в т.ч. и основном.
← →
ГореПрограммер (2006-11-07 15:11) [40]
> for i := 0 to ar_excel.count - 1 do
> begin
> if Terminated then
> Break;
> index:=i;
> Synchronize(sinform);
> end;
Да вроде по этому коду он должен выполнится ar_excel.count число раз. а не бесконечно
Страницы: 1 2 3 вся ветка
Форум: "Начинающим";
Текущий архив: 2006.11.26;
Скачать: [xml.tar.bz2];
Память: 0.54 MB
Время: 0.048 c