Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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.044 c
2-1162995132
doctor
2006-11-08 17:12
2006.11.26
TADOConnection.ConnectionString - редактирование


4-1150551148
PRT
2006-06-17 17:32
2006.11.26
спрятать чужое приложение


15-1163023829
Орион
2006-11-09 01:10
2006.11.26
Задачка


4-1152899610
TWINc
2006-07-14 21:53
2006.11.26
WinProc


15-1162648684
Колдун
2006-11-04 16:58
2006.11.26
Нужна схема





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский