|
Вопрос # 4 914/ вопрос открыт / |
|
Здравствуйте!
Подскажите, что не так делаю.
При создании, компилировании в среде все работает, после сохранения
и запуска готового приложения, не выводятся данные в Memo, из дочернего потока в основной.
Приложение: Переключить в обычный режим-
- Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
- Dialogs, StdCtrls, XPMan,CommL, RzCmboBx, ExtCtrls, RzBckgnd, RzLabel,MyThread;
-
- const
- cmRxByte = wm_User;
-
- type
- TForm1 = class(TForm)
- Button1: TButton;
- Button2: TButton;
- Memo1: TMemo;
- Label1: TLabel;
- Label2: TLabel;
- ..............
- procedure Button1Click(Sender: TObject);
- procedure Button2Click(Sender: TObject);
- procedure Button3Click(Sender: TObject);
- procedure Button4Click(Sender: TObject);
-
- private
- co:TcountObj;
-
- procedure ObrMess(var Msg : TMessage); message cmRxByte;
- public
- { Public declarations }
-
- end;
-
- var
- Form1:TForm1; S : string;
- otk,q,repOff:Boolean; cnt1:integer;
- implementation
-
- {$R *.dfm}
-
- { TForm1 }
-
-
-
- procedure TForm1.Button1Click(Sender: TObject);
-
- .........
- end;
-
- procedure TForm1.Button2Click(Sender: TObject);
-
- ..............
-
- end;
-
-
- procedure TForm1.Button3Click(Sender: TObject); //peredat
- .....................
- end;
-
-
- procedure TForm1.Button4Click(Sender: TObject);
- ........
- end;
-
- procedure TForm1.ObrMess(var Msg: TMessage);// message cmRxByte;
-
- var
- cnt,i: integer;
- Buff : ^char;
- str : string;
- begin
-
- Buff := Pointer(Msg.WParam);
- Cnt := Msg.LParam;
- str := '';
- for i := 0 to cnt-1 do
- begin
- str := str+(Buff^);
- inc(Buff);
-
- end;
- Cnt1 := Cnt + 1;
- Memo1.Lines.Add(str);
- label4.Caption := intToStr(Cnt1);
- Buff := nil;
- Pointer(Msg.WParam) := nil;
- end;
-
-
-
- end.
-
- ////////////////////////////////////////////////////////////////
-
-
-
-
- interface
-
- uses
- CommL, Classes,SysUtils,Windows;
-
- type
- TcountObj = class(TThread)
- private
-
-
-
- protected
- procedure Execute; override;
- end;
-
- implementation
-
- uses Hendle7;
-
-
-
- procedure TcountObj.Execute;
- var
- comstat : Tcomstat;
- dwmask,dwError: DWORD;
- OverRead : OverLapped;
-
- PBuf : Pointer;
- dwRead:DWORD;
- Count: integer;
- buf : array[0..255] of char;
-
-
- begin
- .............................
- end;
- begin
- readfile(com,buf,dwRead,dwRead,@OverRead);
- PBuf := @Buf;
-
- // form1.Memo1.Lines.Add(Buf);
- postMessage(form1.Handle, cmRxByte,Integer(PBuf),dwRead );
- sleep(5);
- if terminated then
- PBuf := Nil
- end;
- end;
- end;
-
-
-
- end.
 |
Вопрос задал: alexsandr (статус: Посетитель)
Вопрос отправлен: 13 января 2011, 16:32
Состояние вопроса: открыт, ответов: 0.
|
Мини-форум вопроса
Всего сообщений: 12; последнее сообщение — 19 января 2011, 03:15; участников в обсуждении: 5.
|
mirt.steelwater (статус: Посетитель), 13 января 2011, 17:19 [#1]:
хм. может нужно делать отправку сообщения основному потоку через Synhronize? я не уверен, но form1.Handle может не читаться без этого. почему бы не передавать его в конструктор TcountObj. при синхронизации можно делать именно так form1.Memo1.Lines.Add(Buf); но в синхронизирующем методе.
попробуй использовать мой класс потока
http://bad-magician.od.ua/files/DLLThreads.txt
Ⓐ свобода сопротивление солидарность
|
|
Вадим К (статус: Академик), 13 января 2011, 17:53 [#2]:
первая и главная проблема в том, что используется PostMessage, а не SendMessage.
А если использовать его, то пропадает вся необходимость делать такой корявейший ход (заполнение переменной по одному символу в основном треде - это пример ужаснейшего кода).
Можно просто у треда сделать свойство текстового типа и передавать через него все текстовые данные.
sleep(5); появилось, так как программа падала?
Галочка "подтверждения прочтения" - вселенское зло.
|
|
min@y™ (статус: Доктор наук), 13 января 2011, 18:03 [#3]:
Слышь, аффтар, мож всё-таки сначала почитаешь парочку статей про TThread и, особенно, про его метод Synchronize()? В рунете это всё давным давно разжёвано так, что даже полный даун понять должен. Ссылки дать или сам нагуглишь?
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
alexsandr (статус: Посетитель), 13 января 2011, 18:14 [#4]:
Это у меня приложение для работы с СОМ портом в асинхронном режиме.
При выводе на форму при помощи synchronize или SendMessage будет приостанавливаться поток в котором организовано чтение из порта, а это приведет к потере данных, поскольку может совпасть время вывода на форму и время прихода данных.
Sleep() чтобы не нагружать сисеему бесполезной работой
|
|
min@y™ (статус: Доктор наук), 13 января 2011, 18:31 [#5]:
Цитата (alexsandr):
При выводе на форму при помощи synchronize или SendMessage будет приостанавливаться поток в котором организовано чтение из порта, а это приведет к потере данных, поскольку может совпасть время вывода на форму и время прихода данных.
А ты пробовал? Попробуй сначала.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
alexsandr (статус: Посетитель), 13 января 2011, 18:33 [#6]:
да есть наработка
|
|
min@y™ (статус: Доктор наук), 13 января 2011, 18:35 [#7]:
Это шож за устройство такое, которое лепит поток данных в порт не по запросу, а просто как пулемёт? В этом случае читать порт надо непрерывно (загрузка CPU = 100%), ставить данные в очередь и передавать её на обработку другому потоку.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
Вадим К (статус: Академик), 13 января 2011, 18:39 [#8]:
Цитата (alexsandr):
При выводе на форму при помощи synchronize или SendMessage будет приостанавливаться поток в котором организовано чтение из порта
конечно.
Цитата (alexsandr):
а это приведет к потере данных, поскольку может совпасть время вывода на форму и время прихода данных.
Да пусть совпадает. подождет ввод с порта. если данные отобразятся на 0.01 с позже, ничего не произойдет. А у порта есть буфер.
А вот код, который Вы привели очень опасный. припустим, что вывод на форму по какой то причине затянулся больше, чем на 5 секунд. вот тут будет бяка.
Цитата (min@y™):
Sleep() чтобы не нагружать сисеему бесполезной работой
системе все равно, висеть на чтении данных с порта или в sleep. в любом случае поток будет заторможен. Но только с sleep он будет медленнее реагировать.
Галочка "подтверждения прочтения" - вселенское зло.
|
|
alexsandr (статус: Посетитель), 13 января 2011, 19:33 [#9]:
Ну почему же все таки при компилировании в среде все работает, а после сохранения и запуска готового приложения, не выводятся данные в Memo, может я что то напартачил с указателями.
|
|
Вадим К (статус: Академик), 13 января 2011, 23:13 [#10]:
вот именно - указатели.
Есть такое понятие - UB - неопределенное поведение.
Вы пытаетесь в коде получать доступ к указателю, который на момент чтения из него может не существовать.
Для эксперимента, попробуйте все таки заменить postmessage на sendmessage и убрать sleep. если заработает, тогда будем говорить о другом. Если нет, тогда о третьем.
А просто спорить о том, почему плохой код не работает - нет смысла.
Галочка "подтверждения прочтения" - вселенское зло.
|
|
mirt.steelwater (статус: Посетитель), 14 января 2011, 11:34 [#11]:
рекомендую разделить функционал и интерфейс.
почему бы не записывать данные, получаемые потоком из сом-порта в базу данных - это будет быстро и гарантированно. а затем с этими данными можно делать что основной программе угодно - вычислять чего-то, апдейтить запись и записывать в поле результата что-то (если есть какие-то вычисления). затем функционал отображения извлекает данные и отображает.
Ⓐ свобода сопротивление солидарность
|
|
bugmenot (статус: 3-ий класс), 19 января 2011, 03:15 [#12]:
> В этом случае читать порт надо непрерывно (загрузка CPU = 100%)
Вздор, WaitCommEvent для кого придумали?
И нет, за последние месяцы в Паскале не появилось UB
виконання програми розпочинається з того самого мiсця, де призупинилося.
|
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|