Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 4 914

/ вопрос открыт /

Здравствуйте!

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

Приложение:
  1.  
  2. Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  3. Dialogs, StdCtrls, XPMan,CommL, RzCmboBx, ExtCtrls, RzBckgnd, RzLabel,MyThread;
  4.  
  5. const
  6. cmRxByte = wm_User;
  7.  
  8. type
  9. TForm1 = class(TForm)
  10. Button1: TButton;
  11. Button2: TButton;
  12. Memo1: TMemo;
  13. Label1: TLabel;
  14. Label2: TLabel;
  15. ..............
  16. procedure Button1Click(Sender: TObject);
  17. procedure Button2Click(Sender: TObject);
  18. procedure Button3Click(Sender: TObject);
  19. procedure Button4Click(Sender: TObject);
  20.  
  21. private
  22. co:TcountObj;
  23.  
  24. procedure ObrMess(var Msg : TMessage); message cmRxByte;
  25. public
  26. { Public declarations }
  27.  
  28. end;
  29.  
  30. var
  31. Form1:TForm1; S : string;
  32. otk,q,repOff:Boolean; cnt1:integer;
  33. implementation
  34.  
  35. {$R *.dfm}
  36.  
  37. { TForm1 }
  38.  
  39.  
  40.  
  41. procedure TForm1.Button1Click(Sender: TObject);
  42.  
  43. .........
  44. end;
  45.  
  46. procedure TForm1.Button2Click(Sender: TObject);
  47.  
  48. ..............
  49.  
  50. end;
  51.  
  52.  
  53. procedure TForm1.Button3Click(Sender: TObject); //peredat
  54. .....................
  55. end;
  56.  
  57.  
  58. procedure TForm1.Button4Click(Sender: TObject);
  59. ........
  60. end;
  61.  
  62. procedure TForm1.ObrMess(var Msg: TMessage);// message cmRxByte;
  63.  
  64. var
  65. cnt,i: integer;
  66. Buff : ^char;
  67. str : string;
  68. begin
  69.  
  70. Buff := Pointer(Msg.WParam);
  71. Cnt := Msg.LParam;
  72. str := '';
  73. for i := 0 to cnt-1 do
  74. begin
  75. str := str+(Buff^);
  76. inc(Buff);
  77.  
  78. end;
  79. Cnt1 := Cnt + 1;
  80. Memo1.Lines.Add(str);
  81. label4.Caption := intToStr(Cnt1);
  82. Buff := nil;
  83. Pointer(Msg.WParam) := nil;
  84. end;
  85.  
  86.  
  87.  
  88. end.
  89.  
  90. ////////////////////////////////////////////////////////////////
  91.  
  92.  
  93.  
  94.  
  95. interface
  96.  
  97. uses
  98. CommL, Classes,SysUtils,Windows;
  99.  
  100. type
  101. TcountObj = class(TThread)
  102. private
  103.  
  104.  
  105.  
  106. protected
  107. procedure Execute; override;
  108. end;
  109.  
  110. implementation
  111.  
  112. uses Hendle7;
  113.  
  114.  
  115.  
  116. procedure TcountObj.Execute;
  117. var
  118. comstat : Tcomstat;
  119. dwmask,dwError: DWORD;
  120. OverRead : OverLapped;
  121.  
  122. PBuf : Pointer;
  123. dwRead:DWORD;
  124. Count: integer;
  125. buf : array[0..255] of char;
  126.  
  127.  
  128. begin
  129. .............................
  130. end;
  131. begin
  132. readfile(com,buf,dwRead,dwRead,@OverRead);
  133. PBuf := @Buf;
  134.  
  135. // form1.Memo1.Lines.Add(Buf);
  136. postMessage(form1.Handle, cmRxByte,Integer(PBuf),dwRead );
  137. sleep(5);
  138. if terminated then
  139. PBuf := Nil
  140. end;
  141. end;
  142. end;
  143.  
  144.  
  145.  
  146. end.


alexsandr Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: alexsandr (статус: Посетитель)
Вопрос отправлен: 13 января 2011, 16:32
Состояние вопроса: открыт, ответов: 0.


Мини-форум вопроса

Всего сообщений: 12; последнее сообщение — 19 января 2011, 03:15; участников в обсуждении: 5.
mirt.steelwater

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™

min@y™ (статус: Доктор наук), 13 января 2011, 18:03 [#3]:

Слышь, аффтар, мож всё-таки сначала почитаешь парочку статей про TThread и, особенно, про его метод Synchronize()? В рунете это всё давным давно разжёвано так, что даже полный даун понять должен. Ссылки дать или сам нагуглишь?
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
alexsandr

alexsandr (статус: Посетитель), 13 января 2011, 18:14 [#4]:

Это у меня приложение для работы с СОМ портом в асинхронном режиме.
При выводе на форму при помощи synchronize или SendMessage будет приостанавливаться поток в котором организовано чтение из порта, а это приведет к потере данных, поскольку может совпасть время вывода на форму и время прихода данных.

Sleep() чтобы не нагружать сисеему бесполезной работой
min@y™

min@y™ (статус: Доктор наук), 13 января 2011, 18:31 [#5]:

Цитата (alexsandr):

При выводе на форму при помощи synchronize или SendMessage будет приостанавливаться поток в котором организовано чтение из порта, а это приведет к потере данных, поскольку может совпасть время вывода на форму и время прихода данных.

А ты пробовал? Попробуй сначала.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
alexsandr

alexsandr (статус: Посетитель), 13 января 2011, 18:33 [#6]:

да есть наработка
min@y™

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

alexsandr (статус: Посетитель), 13 января 2011, 19:33 [#9]:

Ну почему же все таки при компилировании в среде все работает, а после сохранения и запуска готового приложения, не выводятся данные в Memo, может я что то напартачил с указателями.
Вадим К

Вадим К (статус: Академик), 13 января 2011, 23:13 [#10]:

вот именно - указатели.
Есть такое понятие - UB - неопределенное поведение.
Вы пытаетесь в коде получать доступ к указателю, который на момент чтения из него может не существовать.
Для эксперимента, попробуйте все таки заменить postmessage на sendmessage и убрать sleep. если заработает, тогда будем говорить о другом. Если нет, тогда о третьем.

А просто спорить о том, почему плохой код не работает - нет смысла.
Галочка "подтверждения прочтения" - вселенское зло.
mirt.steelwater

mirt.steelwater (статус: Посетитель), 14 января 2011, 11:34 [#11]:

рекомендую разделить функционал и интерфейс.
почему бы не записывать данные, получаемые потоком из сом-порта в базу данных - это будет быстро и гарантированно. а затем с этими данными можно делать что основной программе угодно - вычислять чего-то, апдейтить запись и записывать в поле результата что-то (если есть какие-то вычисления). затем функционал отображения извлекает данные и отображает.
Ⓐ свобода сопротивление солидарность
bugmenot

bugmenot (статус: 3-ий класс), 19 января 2011, 03:15 [#12]:

> В этом случае читать порт надо непрерывно (загрузка CPU = 100%)
Вздор, WaitCommEvent для кого придумали?

И нет, за последние месяцы в Паскале не появилось UB
виконання програми розпочинається з того самого мiсця, де призупинилося.

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 16:47
Выполнено за 0.03 сек.