![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Обращение к VCL объектам из потока
markers © (2009-02-11 12:33:00)Здраствуйте!
Давно не писал потоки, а тут потребовалось.....
Изучил доку по потокам 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
KSergey (2009-02-11 13:17:00) [41]> Anatoly Podgoretsky © (11.02.09 13:15) [18]
> Верный последователь Архангельского.
Это да, но где трабла?
прочем есть подозрение, что она вообще где-то не здесь, не в этом куске.
Anatoly Podgoretsky (2009-02-11 13:15:00) [42]> markers (11.02.2009 12:33:00) [0]
Верный последователь Архангельского.
KSergey (2009-02-11 13:13:00) [43]> markers © (11.02.09 12:59) [14]
> Знаете после угробленного полдня на всё это, уже чего только не пробуешь.
Подумаешь пол-дня. Гы, всего-то??
Ну и как бы против здравого смысла-то идти все равно не надо ведь.
KSergey (2009-02-11 13:12:00) [44]если честно, то я не вижу в чем может быть проблема...
к стати, вероятно не в совсем правильную точку, где проблема, выкидывает
Так мне думается.
А может вообще беда в том, что execute вызывается руками, может унутри TThread это как-приводит к проблемам, смотреть лень.
markers (2009-02-11 13:02:00) [45]Зы: Обращение к объектам формы и класса формы (к примеру по нажатию кнопки старт), изменения объектов происходит штатно.
markers (2009-02-11 12:59:00) [46]To Palladin
UpdForm: TUpdForm создаётся в родительской форме.....
> одного вызова в synchronize процедуры нафик не сдался...
Я пробовал сначала без вызова синхронизации, проблема таже....
To KSergey
> И после этого пишете вот такое?!!
Знаете после угробленного полдня на всё это, уже чего только не пробуешь.
Сергей М. (2009-02-11 12:56:00) [47]
> Не пользовался инструментом этим пока-что
Самое время начать пользоваться.
markers (2009-02-11 12:53:00) [48]To: Сергей М.
Не пользовался инструментом этим пока-что, но вроде говорит "Inaccessible value" Кстати Log это Tmemo положеный на форме
KSergey (2009-02-11 12:52:00) [49]> markers © (11.02.09 12:33)
> Изучил доку по потокам
И после этого пишете вот такое?!!
MyThread. execute; // Пробовал в начале Resume, эффект тот-же
Тогда надо перечитать.
Palladin (2009-02-11 12:51:00) [50]UpdForm: TUpdForm; - объекта не существует, да и вообще, весь код фтопку, обращение к глобальным переменным без синхронизации, поток всего из одного вызова в synchronize процедуры нафик не сдался...
Сергей М. (2009-02-11 12:49:00) [51]
> markers © (11.02.09 12:46) [6]
Что говорит Evaluate/Modify по поводу содержимого поля Log ?
markers (2009-02-11 12:48:00) [52]Вот точный код ошибки:
Access violation at address 0050F0EA in module 'shop.exe'. Read of address 0000031C.
Palladin (2009-02-11 12:47:00) [53]хотя нет.... прошу прощения... еле нашел откуда оно вызывается
markers (2009-02-11 12:46:00) [54]Уважаемый Сергей М., я поставил комент у той строчки именно потому-что именно она и даёт ексцепшн!!! я уже полдня сижу в отладке и при любом обращении объектам на форме происходит эксепшн...
Palladin (2009-02-11 12:45:00) [55]
> Сергей М. © (11.02.09 12:42) [2]
там и так видно, что может еррорить, скорее всего Canvas don't allow drawing
KSergey (2009-02-11 12:45:00) [56]сделайте маленькиймодельный пример, где воспроизводится данная проблема и, если разобраться не удасться - можно спросить.
А копаться в огороде где много неотносящегося к делу...
markers (2009-02-11 12:43:00) [57]TO: Palladin
Читал я то тоже, нинашёл ничего такого что я делаю не так.... Ткните тогда уж пальцем плиз?
Кстати, если закоментить вызов изменения объекта VCL то всё отрабатывает на ура. к прмиеру если вставить вывод сообщения то всё пашет.
Сергей М. (2009-02-11 12:42:00) [58]
> поставил комент на том месте где еррорит
Надо не "комент" ставить, а точку останова, ловить ее отладчиком и выяснять где и что "еррорит"
Palladin (2009-02-11 12:39:00) [59]http://www.delphimaster.ru/articles/panov/