Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 15.03.2017, 18:29   #1
Серёга Русич
Пользователь
 
Регистрация: 11.05.2011
Сообщений: 31
По умолчанию Цикл в потоке прерывается

Доброго времени суток!
Есть цикл, который выполняется в потоке. Через определенное время цикл прерывается: просто останавливается и не выполняется никаких дальнейших действий. В исходной таблице, откуда берутся данные - ошибок нет, цикл может прерываться на разных записях.
Как определить, с чем это может быть связано?

Код программы:
Код:
procedure TMyThread.Execute;
begin
NomerStroki:=StrToInt(Form1.Edit1.Text)-1;
KolvoKlientov:=0;
Form1.ProgressBar1.Max:=(StrToInt(Form1.Edit2.Text)-StrToInt(Form1.Edit1.Text))+1;
For OdnaStroka:=1 to (StrToInt(Form1.Edit2.Text)-StrToInt(Form1.Edit1.Text))+1 do
begin
NomerStroki:=NomerStroki+1;
KolvoKlientov:=KolvoKlientov+1;
ClientDir:=ExtractFilePath(ParamStr(0)) + 'Content\Done\' + Form1.StringGrid1.Cells[1, NomerStroki] + ' ' + Form1.StringGrid1.Cells[2, NomerStroki] + ' ' + Form1.StringGrid1.Cells[3, NomerStroki] + ' ' + Form1.StringGrid1.Cells[4, NomerStroki];
CreateDir(ClientDir);

Progress:=KolvoKlientov+1;
Synchronize(SetProgress);
end;
end;

procedure TMyThread.SetProgress;
begin
DataReg:=Copy(Form1.StringGrid1.Cells[16, NomerStroki], 4, 2);

Form2.Label1.Caption:=Form1.StringGrid1.Cells[7, NomerStroki];   

PrintColor:=Random(8);
case PrintColor of
0:  Form2.label1.Font.Color:=RGB(80,70,83);
1:  Form2.label1.Font.Color:=RGB(54,48,56);
2:  Form2.label1.Font.Color:=RGB(64,61,65);
3:  Form2.label1.Font.Color:=RGB(71,64,71);
4:  Form2.label1.Font.Color:=RGB(30,30,30);
5:  Form2.label1.Font.Color:=RGB(54,49,42);
6:  Form2.label1.Font.Color:=RGB(63,45,45);
7:  Form2.label1.Font.Color:=RGB(45,25,25);
end;


Vozrast:=StrToInt((Copy(Form1.StringGrid1.Cells[10, NomerStroki], 7, 4) ))-StrToInt((Copy(Form1.StringGrid1.Cells[4, NomerStroki], 7, 4) ));
case Vozrast of
13..19:  VozrastFolder:='14-20';
20..44:  VozrastFolder:='20-45';
45..100:  VozrastFolder:='45+';
end;

KFpics:=0;
  if FindFirst(ExtractFilePath(ParamStr(0)) + 'Data\Photo\' + '\' + VozrastFolder +'\*.jpg', faAnyFile - faDirectory - faVolumeID, KFfs) = 0
    then
    repeat
      inc(KFpics);
    until
      FindNext(KFfs) <> 0;
  FindClose(KFfs);

KolvoFotok := KFpics-1;
Form2.Photo.Picture.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'Data\Photo\' + '\' + VozrastFolder + '\' + IntToStr(Random(KolvoFotok)) + '.jpg');

Form2.SignZav.Picture.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'Data\Signatures\' + IntToStr(Random(79)) + '.png');

StrZav:=Copy(Form1.StringGrid1.Cells[1, NomerStroki], 1, 4)+Copy(Form1.StringGrid1.Cells[2, NomerStroki], 1, 1);
IZav:=length(StrZav);
NachZav:=AnsiUpperCase(copy(StrZav,1,1));
KonecZav:=AnsiLowerCase(copy(StrZav,2,IZav));
StrZav:=NachZav+KonecZav;

Form2.Label5.Top:=StrToInt(StrZavTop1);
Form2.Label5.Caption:=StrZav;
//Репаинт формы
Form2.Repaint;

//Сохранение в файл готового изображения при помощи скриншота
bmp:=tbitmap.Create;
SendJPG:=TJPEGImage.Create;
bmp.Width:=form2.Width;
bmp.Height:=form2.Height;
BitBlt(bmp.Canvas.Handle,0,0,form2.Width,form2.Height,getdc(form2.handle),0,0,SRCCOPY);
SendJPG.Assign(bmp);
Form1.DoneImage.Picture.Assign(SendJPG);
Form1.DoneImage.Picture.SaveToFile(ClientDir + '\' + Form1.StringGrid1.Cells[1, NomerStroki] + ' ' + Form1.StringGrid1.Cells[2, NomerStroki] + ' ' + Form1.StringGrid1.Cells[3, NomerStroki] + ' ' + Form1.StringGrid1.Cells[4, NomerStroki] + '_01' + '.jpg');
Form3.SignZav.Picture.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'Data\Signatures\' + IntToStr(Random(79)) + '.png');

//Репаинт формы
Form3.Repaint;

//Сохранеине в файл готового изображения при помощи скриншота
bmp:=tbitmap.Create;
SendJPG:=TJPEGImage.Create;
bmp.Width:=form3.Width;
bmp.Height:=form3.Height;
BitBlt(bmp.Canvas.Handle,0,0,form3.Width,form3.Height,getdc(form3.handle),0,0,SRCCOPY);
SendJPG.Assign(bmp);
Form1.DoneImage.Picture.Assign(SendJPG);
Form1.DoneImage.Picture.SaveToFile(ClientDir + '\' + Form1.StringGrid1.Cells[1, NomerStroki] + ' ' + Form1.StringGrid1.Cells[2, NomerStroki] + ' ' + Form1.StringGrid1.Cells[3, NomerStroki] + ' ' + Form1.StringGrid1.Cells[4, NomerStroki] + '_02' + '.jpg');

//Внести данные из таблицы в лейблы
Form4.Label9.Caption:=Form1.StringGrid1.Cells[28, NomerStroki];

//Репаинт формы
Form4.Repaint;

//Сохранеине в файл готового изображения при помощи скриншота
bmp:=tbitmap.Create;
SendJPG:=TJPEGImage.Create;
bmp.Width:=form4.Width;
bmp.Height:=form4.Height;
BitBlt(bmp.Canvas.Handle,0,0,form4.Width,form4.Height,getdc(form4.handle),0,0,SRCCOPY);
SendJPG.Assign(bmp);
Form1.DoneImage.Picture.Assign(SendJPG);
Form1.DoneImage.Picture.SaveToFile(ClientDir + '\' + Form1.StringGrid1.Cells[1, NomerStroki] + ' ' + Form1.StringGrid1.Cells[2, NomerStroki] + ' ' + Form1.StringGrid1.Cells[3, NomerStroki] + ' ' + Form1.StringGrid1.Cells[4, NomerStroki] + '_03' + '.jpg');


Form1.Label2.Caption:='Готово: ' + IntToStr(KolvoKlientov) + '/' + IntToStr((StrToInt(Form1.Edit2.Text)-StrToInt(Form1.Edit1.Text))+1);
Form1.Repaint;
  Form1.ProgressBar1.Position:=Progress;

  If OdnaStroka=(StrToInt(Form1.Edit2.Text)-StrToInt(Form1.Edit1.Text))+1 then
begin
Form1.Repaint;
Form1.Button1.Enabled:=True;
Form1.Button2.Enabled:=True;
Form1.Edit1.Enabled:=True;
Form1.Edit2.Enabled:=True;
Form1.Repaint;
end;

end;
Запуск цикла:
Код:
procedure TForm1.Button2Click(Sender: TObject);
begin
Button1.Enabled:=False;
Button2.Enabled:=False;
Edit1.Enabled:=False;
Edit2.Enabled:=False;
MyThread:=TMyThread.Create;
MyThread.FreeOnTerminate:=True;
MyThread.Priority:=tpHigher;
MyThread.Resume;
end;
Серёга Русич вне форума Ответить с цитированием
Старый 15.03.2017, 19:48   #2
northener
ПШП
Участник клуба
 
Регистрация: 15.07.2013
Сообщений: 1,859
По умолчанию

Цитата:
Сообщение от Серёга Русич Посмотреть сообщение
Есть цикл, который выполняется в потоке
А нафига тут нужен поток, в котором практически ничего не делается?
northener вне форума Ответить с цитированием
Старый 15.03.2017, 20:16   #3
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 19,042
По умолчанию

Почти все выполняется в основном потоке. Зачем поток?
Цитата:
Как определить, с чем это может быть связано?
Для начала все обращения к vcl нужно синхронизировать, в т.ч. и для чтения, типа NomerStroki:=StrToInt(Form1.Edit1.T ext)-1; Тогда точно все будет в основном потоке ))
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 15.03.2017, 20:37   #4
Серёга Русич
Пользователь
 
Регистрация: 11.05.2011
Сообщений: 31
По умолчанию

Цитата:
Сообщение от northener Посмотреть сообщение
А нафига тут нужен поток, в котором практически ничего не делается?
Программой создается по 3 графических файла для каждой из 500-3000 записей, следовательно - цикл выполняется довольно таки длительное время


Цитата:
Сообщение от Аватар Посмотреть сообщение
Почти все выполняется в основном потоке. Зачем поток?
Для начала все обращения к vcl нужно синхронизировать, в т.ч. и для чтения, типа NomerStroki:=StrToInt(Form1.Edit1.T ext)-1; Тогда точно все будет в основном потоке ))
Т.е. в TMyThread.Execute мне нужно прописать только Synchronize(SetProgress), а все остальное действия выполнять в TMyThread.SetProgress?
Серёга Русич вне форума Ответить с цитированием
Старый 15.03.2017, 20:48   #5
northener
ПШП
Участник клуба
 
Регистрация: 15.07.2013
Сообщений: 1,859
По умолчанию

Цитата:
Сообщение от Серёга Русич Посмотреть сообщение
Т.е. в TMyThread.Execute мне нужно прописать только Synchronize(SetProgress), а все остальное действия выполнять в TMyThread.SetProgress?
Тогда поток просто можно выбросить. Ибо тогда как сказал
Цитата:
Сообщение от Аватар Посмотреть сообщение
Тогда точно все будет в основном потоке ))
northener вне форума Ответить с цитированием
Старый 15.03.2017, 21:54   #6
Серёга Русич
Пользователь
 
Регистрация: 11.05.2011
Сообщений: 31
По умолчанию

Цитата:
Сообщение от northener Посмотреть сообщение
Тогда поток просто можно выбросить. Ибо тогда как сказал
Единственное, для чего я использую поток - чтоб программа не вешалась
Серёга Русич вне форума Ответить с цитированием
Старый 15.03.2017, 22:06   #7
northener
ПШП
Участник клуба
 
Регистрация: 15.07.2013
Сообщений: 1,859
По умолчанию

В данном конкретном случае достаточно грамотно использовать Application.ProcessMessages. Эффект будет такой же, а геморроя гораздо меньше.
northener вне форума Ответить с цитированием
Старый 15.03.2017, 22:10   #8
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,515
По умолчанию

Цитата:
Через определенное время цикл прерывается: просто останавливается и не выполняется никаких дальнейших действий.
путь 1. если не знаешь что происходит в твой программе то как и подобает программисту надо сделать логирование, в том числе (и даже вероятно в первую очередь) логирование исключительных ситуаций.

путь 2. написать это без потоков, получить ошибку EOutfMemory скорее всего и начать думать почему и как это исправить.

имеем кучу создаваемых в цикле объектов без их освобождения.
программа — запись алгоритма на языке понятном транслятору
evg_m вне форума Ответить с цитированием
Старый 16.03.2017, 09:20   #9
Серёга Русич
Пользователь
 
Регистрация: 11.05.2011
Сообщений: 31
По умолчанию

Цитата:
Сообщение от northener Посмотреть сообщение
В данном конкретном случае достаточно грамотно использовать Application.ProcessMessages. Эффект будет такой же, а геморроя гораздо меньше.
Я пробовал вставлять Application.ProcessMessages. Но куда бы я его не вставил - программа перестает работать, как только дойдет до этой строчки кода. Если вставить в самом конце цикла - следовательно, цикл выполняется только один раз.
Понимаю, что балбес я - но так и не понял, в чем проблема и что я сделал не так с ним


Цитата:
Сообщение от evg_m Посмотреть сообщение
путь 1. если не знаешь что происходит в твой программе то как и подобает программисту надо сделать логирование, в том числе (и даже вероятно в первую очередь) логирование исключительных ситуаций.

путь 2. написать это без потоков, получить ошибку EOutfMemory скорее всего и начать думать почему и как это исправить.

имеем кучу создаваемых в цикле объектов без их освобождения.
путь 1 - попробую. Над логированием я даже не задумывался...
путь 2 - у меня же только bmp:=tbitmap.Create и SendJPG:=TJPEGImage.Create создаются... Щас попробую их освободить
Серёга Русич вне форума Ответить с цитированием
Старый 16.03.2017, 11:53   #10
Slym
Участник клуба
 
Регистрация: 07.12.2011
Сообщений: 1,025
По умолчанию

не проще отполировать алгоритм, а не бороться с его шершавостью?
Не стесняемся, плюсуем!
Slym вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Почему прерывается работа программы после чтения их файла? Вероника99 Помощь студентам 1 26.01.2014 19:06
Как из метода X в потоке А, вызвать метод Y и чтобы он работал в потоке B ? lawliet93 C# (си шарп) 0 09.03.2013 18:16
Почему прерывается поиск в MS. Word Pavel229 Общие вопросы Delphi 0 18.07.2011 10:22
Действие lines.add не завершает свего дествия, т.е прерывается NiKiToZZ- Помощь студентам 1 13.02.2011 13:53
Поток прерывается самостоятельно Ferrum26 Общие вопросы Delphi 7 28.07.2010 15:36