Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2009.04.05;
Скачать: [xml.tar.bz2];

Вниз

Обращение к 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.56 MB
Время: 0.007 c
2-1234336304
Andrewtitoff
2009-02-11 10:11
2009.04.05
Access Violation


8-1192560705
MikeZ
2007-10-16 22:51
2009.04.05
Воспроизведение WAV-файла с определенной позиции


2-1234344792
markers
2009-02-11 12:33
2009.04.05
Обращение к VCL объектам из потока


15-1233658361
dark_volk
2009-02-03 13:52
2009.04.05
FastMM4


11-1199030958
Efir
2007-12-30 19:09
2009.04.05
Библиотека KOLATL





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский