Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.04.05;
Скачать: CL | DM;

Вниз

Обращение к VCL объектам из потока   Найти похожие ветки 

 
markers ©   (2009-02-11 12:33) [0]

Здраствуйте!
Давно не писал потоки, а тут потребовалось.....
Изучил доку по потокам http://www.interface.ru/home.asp?artId=6105 и на данном сайте везде из потока прекрасно обращяются к объектам VCL, а у меня эксепшн....
Имеем главную форму которая пораждает в случае необходимости дополнительную форму с потоками таким способом:
procedure TMainForm.ChekUpdatesMBTClick(Sender: TObject);
var updForm : TUpdForm;
begin
 updForm := TUpdForm.Create(Self);
 with updForm do
  begin
   ShowModal;
   Free;
  end;
end;

Вот код вызывеемой формы:
unit UpdateFrm;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls, ExtCtrls, XPMenu, SystemUnit, ComCtrls, Buttons;

type
 OperType = (otuCheck, otuProg, otuBD, otuImages);
 TMyThread = class(tthread)
 private
   UpdateType : OperType;
 protected
   procedure execute; override;
 end;
 TUpdForm = class(TForm)
   GroupBox1: TGroupBox;
   StatusBar: TStatusBar;
   CheckBox1: TCheckBox;
   CheckBox2: TCheckBox;
   CheckBox3: TCheckBox;
   Start: TButton;
   GroupBox2: TGroupBox;
   Cancel: TButton;
   ProgressBar: TProgressBar;
   Log: TMemo;
   StopUpdate: TBitBtn;
   OperStart: TTimer;
   procedure FormCreate(Sender: TObject);
   procedure StartClick(Sender: TObject);
   procedure FormShow(Sender: TObject);
   procedure OperStartTimer(Sender: TObject);
   procedure StopUpdateClick(Sender: TObject);
   procedure Updater_pbi;
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 UpdForm: TUpdForm;
 MyThread : TMyThread;
 CountTraf : Int64;
 NextOper : OperType;
 CurOper : OperType;
 Breaked : Boolean;
 ThreadFinish : Boolean = True;

implementation
{$R *.dfm}
uses MainUnit, RegExpr, IniFiles;

procedure TUpdForm.Updater_pbi;
begin
try
 if CurOper = otuCheck Then
  begin
   Log.Lines.Add("Проверка необходимости обновления ядра программы"); // На этот код возникает Access violetion
   sleep(15);
   ThreadFinish := True;
  end
 else if CurOper = otuProg Then
  begin
   sleep(15);
   ThreadFinish := True;
  end
 else if CurOper = otuBD Then
  begin
   sleep(15);
   ThreadFinish := True;
  end
 else if CurOper = otuImages Then
  begin
   sleep(15);
   ThreadFinish := True;
  end;
except
 on E:Exception do Mess(e.Message, mtError)
end;
end;

{ TMyThread }
procedure TMyThread.execute;
begin
CurOper := UpdateType;
Synchronize(UpdForm.Updater_pbi);
end;

{ TUpdateForm }
procedure TUpdForm.FormCreate(Sender: TObject);
begin
if DrivType = SDT_CDROM then
 begin
  Mess("Обновление баз программы при работе с CD, недоступно!"+#13#10+"Произведите установку программы на жёсткий диск!",mtWarning);
  Cancel.Click;
  exit;
 end;
 if Trim(UpdateServer) = "" then UpdateServer := defupdateserver;
end;

procedure TUpdForm.StartClick(Sender: TObject);
begin
 Log.Clear;
 if MainForm.ChekUpdatesMBT.Tag = 1 then MainForm.ChekUpdatesMBT.Tag := 0; // Нужно для запуска обновления автоматом (Ранее в проге было получено согласие пользователя)
 Log.Lines.Add("Начало обновления");
 NextOper := otuCheck;
 Breaked := False;
 OperStart.Enabled := True;
 StopUpdate.Enabled := False;
end;

procedure TUpdForm.FormShow(Sender: TObject);
begin
 if MainForm.ChekUpdatesMBT.Tag = 1 then Start.Click;
end;

procedure TUpdForm.OperStartTimer(Sender: TObject);
begin
 Application.ProcessMessages;
 inherited;
 if ThreadFinish then
  begin
   ThreadFinish := False;
   MyThread := TMyThread.create(True);
   MyThread.FreeOnTerminate := True;
   MyThread.UpdateType := NextOper;
   MyThread.Priority := tpNormal;
   MyThread.execute; // Пробовал в начале Resume, эффект тот-же

   if NextOper = otuImages then OperStart.Enabled := False
   else if NextOper = otuBD then NextOper := otuImages
   else if NextOper = otuProg then NextOper := otuBD
   else if NextOper = otuCheck then NextOper := otuProg;
  end;
end;

procedure TUpdForm.StopUpdateClick(Sender: TObject);
begin
Breaked := True;
end;

end.

Прошу прощения за кривость кода..... Пробовал сувать код исполняемый в потоке пихать и в Execution и в отдельную функу в классе TMyThread всё одно, ошибка... (поставил комент на том месте где еррорит...). Так же пробовал обращатся к другим объектам а не только к объекту Log типа Tmemo


 
Palladin ©   (2009-02-11 12:39) [1]

http://www.delphimaster.ru/articles/panov/


 
Сергей М. ©   (2009-02-11 12:42) [2]


> поставил комент на том месте где еррорит


Надо не "комент" ставить, а точку останова, ловить ее отладчиком и выяснять где и что "еррорит"


 
markers ©   (2009-02-11 12:43) [3]

TO: Palladin
Читал я то тоже, нинашёл ничего такого что я делаю не так.... Ткните тогда уж пальцем плиз?
Кстати, если закоментить вызов изменения объекта VCL то всё отрабатывает на ура. к прмиеру если вставить вывод сообщения то всё пашет.


 
KSergey ©   (2009-02-11 12:45) [4]

сделайте маленький модельный пример, где воспроизводится данная проблема и, если разобраться не удасться - можно спросить.

А копаться в огороде где много неотносящегося к делу...


 
Palladin ©   (2009-02-11 12:45) [5]


> Сергей М. ©   (11.02.09 12:42) [2]

там и так видно, что может еррорить, скорее всего Canvas don"t allow drawing


 
markers ©   (2009-02-11 12:46) [6]

Уважаемый Сергей М., я поставил комент у той строчки именно потому-что именно она и даёт ексцепшн!!! я уже полдня сижу в отладке и при любом обращении объектам на форме происходит эксепшн...


 
Palladin ©   (2009-02-11 12:47) [7]

хотя нет.... прошу прощения... еле нашел откуда оно вызывается


 
markers ©   (2009-02-11 12:48) [8]

Вот точный код ошибки:
Access violation at address 0050F0EA in module "shop.exe". Read of address 0000031C.


 
Сергей М. ©   (2009-02-11 12:49) [9]


> markers ©   (11.02.09 12:46) [6]


Что говорит Evaluate/Modify по поводу содержимого поля Log ?


 
Palladin ©   (2009-02-11 12:51) [10]

UpdForm: TUpdForm; - объекта не существует, да и вообще, весь код фтопку, обращение к глобальным переменным без синхронизации, поток всего из одного вызова в synchronize процедуры нафик не сдался...


 
KSergey ©   (2009-02-11 12:52) [11]

> markers ©   (11.02.09 12:33)  
> Изучил доку по потокам

И после этого пишете вот такое?!!

 MyThread.execute; // Пробовал в начале Resume, эффект тот-же

Тогда надо перечитать.


 
markers ©   (2009-02-11 12:53) [12]

To: Сергей М.
Не пользовался инструментом этим пока-что, но вроде говорит "Inaccessible value" Кстати Log это Tmemo положеный на форме


 
Сергей М. ©   (2009-02-11 12:56) [13]


> Не пользовался инструментом этим пока-что


Самое время начать пользоваться.


 
markers ©   (2009-02-11 12:59) [14]

To Palladin
UpdForm: TUpdForm создаётся в родительской форме.....


> одного вызова в synchronize процедуры нафик не сдался...


Я пробовал сначала без вызова синхронизации, проблема таже....

To KSergey

> И после этого пишете вот такое?!!

Знаете после угробленного полдня на всё это, уже чего только не пробуешь.


 
markers ©   (2009-02-11 13:02) [15]

Зы: Обращение к объектам формы и класса формы (к примеру по нажатию кнопки старт), изменения объектов происходит штатно.


 
KSergey ©   (2009-02-11 13:12) [16]

если честно, то я не вижу в чем может быть проблема...

к стати, вероятно не в совсем правильную точку, где проблема, выкидывает
Так мне думается.

А может вообще беда в том, что execute вызывается руками, может унутри TThread это как-приводит к проблемам, смотреть лень.


 
KSergey ©   (2009-02-11 13:13) [17]

> markers ©   (11.02.09 12:59) [14]
> Знаете после угробленного полдня на всё это, уже чего только не пробуешь.

Подумаешь пол-дня. Гы, всего-то??
Ну и как бы против здравого смысла-то идти все равно не надо ведь.


 
Anatoly Podgoretsky ©   (2009-02-11 13:15) [18]

> markers  (11.02.2009 12:33:00)  [0]

Верный последователь Архангельского.


 
KSergey ©   (2009-02-11 13:17) [19]

> Anatoly Podgoretsky ©   (11.02.09 13:15) [18]
> Верный последователь Архангельского.

Это да, но где трабла?
прочем есть подозрение, что она вообще где-то не здесь, не в этом куске.


 
Плохиш ©   (2009-02-11 13:21) [20]


> markers ©   (11.02.09 12:59) [14]
>
> To Palladin
> UpdForm: TUpdForm создаётся в родительской форме.....

Да создаётся, только указатель на неё присваивается локальной переменной, о которой модуль, где описана эта форма ничего не знает.


 
KSergey ©   (2009-02-11 13:23) [21]

> Плохиш ©   (11.02.09 13:21) [20]

Ёлы-палы, точно! проглядел :(


 
markers ©   (2009-02-11 13:25) [22]

1) На счёт Execute, повторяю в самом начале дебага, и счас стоит Resume проблема от этого не решилась....
2) Ладно если дебажить не один и тот же на всём протяжении код.... а то что не делаешь всё спотыкается именно об это....
3) Делаю степ-бай-степ, дельфя выкидывает еррор именно при выполнении изменений объекта формы, дальше идёт обработка её try except`ом...
4) Насчёт того что виновник в другом месте, появилась одна мысль, счас проверю.


 
Плохиш ©   (2009-02-11 13:31) [23]


> 3) Делаю степ-бай-степ, дельфя выкидывает еррор именно при
> выполнении изменений объекта формы, дальше идёт обработка
> её try except`ом...

Как баран перед новыми воротами, так и ты с отладчиком. Посмотреть значения переменных при выполнении проблеммной строки мозгов не хватает?


 
Сергей М. ©   (2009-02-11 13:32) [24]


> точно! проглядел


При лицезрении говнокода это обычное дело)


 
Сергей М. ©   (2009-02-11 13:33) [25]


> Плохиш ©   (11.02.09 13:31) [23]


Он получил Inaccessible value и засим успокоился)


 
Плохиш ©   (2009-02-11 13:37) [26]


> Сергей М. ©   (11.02.09 13:33) [25]

Оно и понятно, это ж на чуждом языке написано.


 
markers ©   (2009-02-11 13:45) [27]

Плохиш
KSergey
Точняк!!! Большое спасибо вам и всем остальным :))


 
Anatoly Podgoretsky ©   (2009-02-11 13:48) [28]

> KSergey  (11.02.2009 13:17:19)  [19]

Зачем искать вторую траблу, если первая не устранена.


 
Сергей М. ©   (2009-02-11 13:50) [29]


> Плохиш ©   (11.02.09 13:37) [26]


Буржуи проклятые !
Нет бы написать по рабоче-крестьянски)


 
markers ©   (2009-02-11 14:01) [30]

Я конечно изменяюсь, но думаю что не стоит так сильмо промывать мои косточки.... Почему код как вы его назвали "говнокод"? Просто непридумал как сделать лучше без таймера последовательное выполнение задач в потоке... т.к. мне надо чтоб основной поток небыл загружен для реализации отмены и т.д.. т.к. процессы некоторые продолжительны, либо пользователь захотел отказаться от скачивания обновлений в процессе их скачивания... просто как мне показалось что вызвав и ожидая выполнения потока в обработчике начатия кнопки Старт не избавит основной поток от "задумчевости".... Можно было бы запустить все потоки и идти пить чай, но нужна последовательность... потому сделал таймер чтоб он поглядывал выполнился ли поток, если да то стартовал другой, если выполнился последний поток, отключал таймер сам себя и всё.


 
markers ©   (2009-02-11 14:04) [31]

Была мысль выполнять всю работу в основном потоке, а потокам вызвать и показывать какую-нибудь формочку с текстом "Жуём", нехотелось т.к. множество форм - зло и были ещё причины.


 
Сергей М. ©   (2009-02-11 14:09) [32]


> Почему код как вы его назвали "говнокод"?


Хотя бы потому что его форматирование, мягко говоря, оставляет желать лучшего.
Про логику я промолчу - она не выдерживает никакой критики.


 
Anatoly Podgoretsky ©   (2009-02-11 14:12) [33]

> markers  (11.02.2009 14:01:30)  [30]

Что бы не был заморожен, чаще всего решается с помощью Application/ProcessMessages.


 
markers ©   (2009-02-11 14:19) [34]

Созрела мысль создать поток который будет последовательно стартить другие потоки, но насколько я понял это не гуд, хотя с другой стороны основной поток проги поступает так же как и созданный мною поток.

To: Сергей М.
Ну подскажите свои рекомендации в особенности по логике и по форматированию? Я жду ваших советов!

TO Anatoly Podgoretsky
Дыг, знаю естественно и много где юзаю, однако это не даёт мне возможности во время задумчивости обломать это всё легально по батону "Стоп".

Вообще у меня сам код обновления написан, но так как он выполняется в основном потоке, есть проблемы при медленном соединении (нельзя обломать), потому и занялся потоками.
Спасибо!


 
Сергей М. ©   (2009-02-11 14:36) [35]


> подскажите свои рекомендации


Думаю, что я не ошибусь, если KSergey © не обратил внимания на твой грубейший ляп именно потому, что такое форматирование

procedure TMainForm.ChekUpdatesMBTClick(Sender: TObject);
var updForm : TUpdForm;
begin


на фоне большушего фрагмента кода попросту "замыливает глаз"

А вот так

procedure TMainForm.ChekUpdatesMBTClick(Sender: TObject);
var
   updForm : TUpdForm;
// по одному ид-ру в каждой новой строке и обязательно с общепринятым фиксированным отступом
begin


локальность проблемного идентификатора сразу бы бросилась в глаза.


 
markers ©   (2009-02-11 14:38) [36]

Согласен так правильней, я так делаю когда обяъявляю более 1-й переменной, а когда 1 то так.... Хорошо! Спасибо! Учту! Ещё какие-то притензия, предложения, cоветы?


 
Сергей М. ©   (2009-02-11 14:45) [37]


> markers



> проблемы при медленном соединении (нельзя обломать), потому
> и занялся потоками


Потоки не ускорят соединение.


 
KSergey ©   (2009-02-11 14:47) [38]

> markers ©   (11.02.09 14:38) [36]
>  Ещё какие-то притензия, предложения, cоветы?

Лучше всю задачу обсказать. ТОгда можно посоветовать как это все организовать.
Однако надо четко понимать, что наличие доп. потока (да хоть тыщи) не дает в общем случае возможности немедленно заставлять реагировать приложение на кнопку "стоп". Нажимать дает, реагировать - нет.


 
Anatoly Podgoretsky ©   (2009-02-11 15:13) [39]

> markers  (11.02.2009 14:38:36)  [36]

Аааааааааааааа!


 
KSergey ©   (2009-02-11 16:29) [40]

> Anatoly Podgoretsky ©   (11.02.09 15:13) [39]

Это совет или претензия? :)



Страницы: 1 2 вся ветка

Текущий архив: 2009.04.05;
Скачать: CL | DM;

Наверх




Память: 0.58 MB
Время: 0.016 c
15-1233701918
Германн
2009-02-04 01:58
2009.04.05
RAD Studio 2007 vs BDS 2006


1-1209223583
Zilog
2008-04-26 19:26
2009.04.05
генерация таблиц в RTF формате


15-1233818505
Slider007
2009-02-05 10:21
2009.04.05
С днем рождения ! 31 января 2009 суббота


2-1235107882
Рулан
2009-02-20 08:31
2009.04.05
как работать с dbf


2-1234290981
Denied
2009-02-10 21:36
2009.04.05
Запуск из сервиса на активном Desktop с правами администратора