C++Builder
  Начало   Форум   Помощь Войти Регистрация  
Страниц: [1] 2 3   Вниз
  Печать  
Автор Тема: Create event  (Прочитано 35602 раз)
3JIou
Участник
**

Сказали спасибо: +0/-0
Offline Offline

Сообщений: 55


« : 08 октября 2009, 15:19:57 »

Здравствуйте.
Вопрос такой: как в Билдере создать событие?
Есть функция, которая заполняет массив. Как только массив заполнился, необходимо вызвать событие по этому случаю.
ЗЫ: поиск юзал, гуглил. Подскажите куда копать?
Спасибо за внимание.
Записан
oxotnik
Глобальный модератор
***

Сказали спасибо: +100/-15
Offline Offline

Сообщений: 2425


« Ответ #1 : 08 октября 2009, 15:40:23 »

если в отдельном потоке (по другому не могу представить зачем событие нужно):
http://cbuilder.ru/index.php/topic,4313.msg27538/topicseen.html
Записан
3JIou
Участник
**

Сказали спасибо: +0/-0
Offline Offline

Сообщений: 55


« Ответ #2 : 08 октября 2009, 15:43:08 »

Спасибо за подсказки.
Записан
AVC
Администратор
***

Сказали спасибо: +28/-6
Offline Offline

Сообщений: 1189


« Ответ #3 : 08 октября 2009, 16:34:22 »

Извиняюсь за ложный путь - не в ту сторону подумал Грустный .
Записан
Nikita
Участник
**

Сказали спасибо: +6/-1
Offline Offline

Сообщений: 476


« Ответ #4 : 17 декабря 2011, 19:24:15 »

Присоединяюсь к автору ветки. Так как все таки создать событие в builder? Хочу получить некий аналог потока, но только на событии.

PS однажды создавал события на API но тогда и программа была без VCL.
Записан
Leex
Участник
**

Сказали спасибо: +132/-1
Offline Offline

Сообщений: 577


« Ответ #5 : 17 декабря 2011, 19:55:13 »

Цитировать
Хочу получить некий аналог потока, но только на событии.
Что этим предложением хотел сказать автор?

А для работы с событиями есть CreateEvent, SetEvent и ResetEvent, но они апишные, былдерских аналогов не знаю, скорее всего их нет
Записан
gumi250
Участник
**

Сказали спасибо: +33/-1
Offline Offline

Сообщений: 254


« Ответ #6 : 17 декабря 2011, 20:00:40 »

на сколько я понимаю события разные бывают. Бывают типа Even, а бывают типа onClick(). Ими решаются разные задачи.
Записан
Nikita
Участник
**

Сказали спасибо: +6/-1
Offline Offline

Сообщений: 476


« Ответ #7 : 17 декабря 2011, 20:18:46 »

Что этим предложением хотел сказать автор?

Хочу чтобы то или иное действие обрабатывалось в отдельном событии. Например: при нажатии определенной кнопки выполняется длинный цикл, во время этих вычислений я могу нажать другую кнопку и тем самым запустить еще другое вычисление, тем самым разные события будут одновременно обрабатывать независимые задачи. Только вот хотелось бы запустить второе событие при определенных условиях в коде первого события.

А для работы с событиями есть CreateEvent, SetEvent и ResetEvent, но они апишные, былдерских аналогов не знаю, скорее всего их нет

CreateEvent и иже с ними я пользоваться умею и пользовался. Но там один нюанс, нужно самому свои события отлавливать, а здесь же VCL не даст этого.

Записан
Nikita
Участник
**

Сказали спасибо: +6/-1
Offline Offline

Сообщений: 476


« Ответ #8 : 17 декабря 2011, 20:29:34 »

на сколько я понимаю события разные бывают. Бывают типа Even, а бывают типа onClick(). Ими решаются разные задачи.

Разные то разные, но мне нужно свое событие запустить при определенных условиях допустим из того же onClick().
Записан
Leex
Участник
**

Сказали спасибо: +132/-1
Offline Offline

Сообщений: 577


« Ответ #9 : 17 декабря 2011, 20:44:11 »

Так нужно событие на основе Event-ов или на основе оконных сообщений?
Цитировать
мне нужно свое событие запустить при определенных условиях допустим из того же onClick().
А простой вызов функции чем не устраивает?
Записан
Nikita
Участник
**

Сказали спасибо: +6/-1
Offline Offline

Сообщений: 476


« Ответ #10 : 17 декабря 2011, 20:49:00 »

Так нужно событие на основе Event-ов или на основе оконных сообщений?
На основе Event-ов

А простой вызов функции чем не устраивает?
Хочу некую параллельность сделать. Допустим в длинном цикле нужно скинуть промежуточные данные в файл, вызываю свое событие и цикл дальше считает, не дожидаясь ответа от функции записи данных в файл.
Записан
Leex
Участник
**

Сказали спасибо: +132/-1
Offline Offline

Сообщений: 577


« Ответ #11 : 17 декабря 2011, 21:04:01 »

Что же всех нынче так на треды потянуло?)
это тебе в сторону многопоточности нужно смотреть а не в сторону эвентов.
винапишная функция CreateThread,
Есть VCl-ная обертка, которая зовется TThred.
Записан
Nikita
Участник
**

Сказали спасибо: +6/-1
Offline Offline

Сообщений: 476


« Ответ #12 : 17 декабря 2011, 21:09:37 »

С CreateThread у меня проблем нет, частенько использовал. Но вот с TThred гемор один и ничего с ним сделать не получается, либо вообще не работает, либо наполовину. А так как у меня в проге VCL то либо TThred либо события. Вот я и выбрал события. Выбрал еще потому, что как то читал книгу, там были примеры работы с сетью на основе многопоточности и на основе  событий (вместо двух потоков, слушания сокета и посыл данных были события по прибытии данных и по отправке), вот и вспомнил этот случай. Правда там на API все, поэтому в чистом виде к моей задаче не применить.
У меня задача стоит такая что при определенных условиях в основном цикле вычислений необходимо не прерывая цикл сделать запросы в сеть и отобразить результаты. Как тут без параллелизма?
Записан
Leex
Участник
**

Сказали спасибо: +132/-1
Offline Offline

Сообщений: 577


« Ответ #13 : 17 декабря 2011, 21:28:38 »

Цитировать
А так как у меня в проге VCL то либо TThred либо события
Не путай кислое с мягким, TThred это поток, события - это объекты синхронизации потоков. Соответственно это не одно и тоже
Цитировать
Правда там на API все, поэтому в чистом виде к моей задаче не применить.
не могу понять по какой такой причине?
Цитировать
У меня задача стоит такая что при определенных условиях в основном цикле вычислений необходимо не прерывая цикл сделать запросы в сеть и отобразить результаты. Как тут без параллелизма?

Код
while(1) //основной поток
{
 ...
 if(condition1)
 {
    CreateThread(...&SendToLAN,...);
 }
 ...
 if(condition2)
 {
    CreateThread(...&UpdateScreen,...);
 }
 ....
}
Если не так, то я не понимаю смысла фразы "не прерывая цикл".
Записан
Nikita
Участник
**

Сказали спасибо: +6/-1
Offline Offline

Сообщений: 476


« Ответ #14 : 17 декабря 2011, 22:38:28 »

Код
while(1) //основной поток
{
 ...
 if(condition1)
 {
    CreateThread(...&SendToLAN,...);
 }
 ...
 if(condition2)
 {
    CreateThread(...&UpdateScreen,...);
 }
 ....
}
Если не так, то я не понимаю смысла фразы "не прерывая цикл".

Так я и делал в основном потоке, но некоторые объекты не хотят работать из потока созданного через CreateThread, в частности используемые сторонние веб-сервисы. Как бороться не пойму. Точно знаю что некоторые паралелят эти веб-сервисы, а у меня ступор с их распараллеливанием.

Только вот еще не понял почему через события нельзя такое организовать?
Записан
Leex
Участник
**

Сказали спасибо: +132/-1
Offline Offline

Сообщений: 577


« Ответ #15 : 17 декабря 2011, 23:10:17 »

Цитировать
Как бороться не пойму. Точно знаю что некоторые паралелят эти веб-сервисы, а у меня ступор с их распараллеливанием.
Все распараллелится при грамотной синхронизации, и вдумчивым чтением мануалов
Цитировать
Только вот еще не понял почему через события нельзя такое организовать?
еще раз повторяю: события - это объекты синхронизации потоков. с их помощью одни потоки могут оповещать других о каких-либо событиях, грубо говоря это флаг.
Записан
Nikita
Участник
**

Сказали спасибо: +6/-1
Offline Offline

Сообщений: 476


« Ответ #16 : 17 декабря 2011, 23:21:24 »

Все распараллелится при грамотной синхронизации, и вдумчивым чтением мануалов

Посредством CreateThread это реализуемо? с моими требованиями с программе (использование VCL , веб-сервисов)
Записан
Leex
Участник
**

Сказали спасибо: +132/-1
Offline Offline

Сообщений: 577


« Ответ #17 : 18 декабря 2011, 01:24:42 »

Абсолютно.
единственное отличае это метод Synchronise, для вызова VCLметодов "не" из главного потока. на самом деле, всё что передаётся в эту функцию вконце концов выполняется только в главном потоке, а пока она там выполняется, твой тредик тупо курит в сторонке. Реализована она на мой взгляд топорно - применимо в любом месте треда и в любой задаче, но за счет нехилой потери производительности и потери многопоточности во время ее работы. Я уж не говорю о последствиях зависания какого-либо треда в этой функции. далеко не во всех задачах нужен такой функционал.
её аналог можно легко реализовать самому, причем с учетом конкретной задачи, а следовательно сделать ее более эфективной и безопасной.
« Последнее редактирование: 18 декабря 2011, 01:34:53 от Leex » Записан
gumi250
Участник
**

Сказали спасибо: +33/-1
Offline Offline

Сообщений: 254


« Ответ #18 : 18 декабря 2011, 03:05:43 »

Хочу чтобы то или иное действие обрабатывалось в отдельном событии. Например: при нажатии определенной кнопки выполняется длинный цикл, во время этих вычислений я могу нажать другую кнопку и тем самым запустить еще другое вычисление, тем самым разные события будут одновременно обрабатывать независимые задачи. Только вот хотелось бы запустить второе событие при определенных условиях в коде первого события.
Нажатие на каждую кнопку создает свой поток, который заранее описан. В чем сложность то? Вы хотите создавать второй поток и по кнопке2 и из первого потока?
Записан
Nikita
Участник
**

Сказали спасибо: +6/-1
Offline Offline

Сообщений: 476


« Ответ #19 : 18 декабря 2011, 10:51:20 »

Нажатие на каждую кнопку создает свой поток, который заранее описан. В чем сложность то? Вы хотите создавать второй поток и по кнопке2 и из первого потока?
Хочу создать второй поток из первого только не по кнопке2 а свой, тот который запускается только из первого потока и никак иначе.
Записан
gumi250
Участник
**

Сказали спасибо: +33/-1
Offline Offline

Сообщений: 254


« Ответ #20 : 18 декабря 2011, 11:04:35 »

Цитировать
Хочу создать второй поток из первого только не по кнопке2 а свой, тот который запускается только из первого потока и никак иначе.
А проблема в чем? В создании второго потока из первого или сделать так чтобы второй поток не запускался иными способами?
Записан
Nikita
Участник
**

Сказали спасибо: +6/-1
Offline Offline

Сообщений: 476


« Ответ #21 : 18 декабря 2011, 18:19:20 »

А проблема в чем? В создании второго потока из первого или сделать так чтобы второй поток не запускался иными способами?

В одной из книг я прочитал и видел пример как там на API вместо потоков был использован подход с распараллеливанием с помощью своих событий. А именно, вместо создания двух потоков на слушание порта и на отсылку данных по сети, было все организовано через события: данные пришли, сработало одно событие, данные нужно послать, другое. Но там свои события просто добавлялись в уже имеющиеся виндовые  и обрабатывались общим циклом обработки сообщений. На сколько я понимаю в чистом виде имея VCL и прочие надстройки этот вариант тут применить нельзя, а вот как метод был интересен, вот и подумал может возможно было создать тоже самое но на другом уровне.
Записан
Leex
Участник
**

Сказали спасибо: +132/-1
Offline Offline

Сообщений: 577


« Ответ #22 : 18 декабря 2011, 18:50:12 »

Походу мои посты ушли вникуда.
Не веришь мне - почитай в гугле
Записан
Nikita
Участник
**

Сказали спасибо: +6/-1
Offline Offline

Сообщений: 476


« Ответ #23 : 19 декабря 2011, 10:16:48 »

Походу мои посты ушли вникуда.
Не веришь мне - почитай в гугле

Пойми правильно, посты пошли на пользу и все это я понял, еще раз спасибо. Как только поток заработает как я хотел обязательно отпишусь здесь.  Улыбка
Записан
Nikita
Участник
**

Сказали спасибо: +6/-1
Offline Offline

Сообщений: 476


« Ответ #24 : 20 декабря 2011, 16:53:20 »

Абсолютно.
единственное отличае это метод Synchronise, для вызова VCLметодов "не" из главного потока. на самом деле, всё что передаётся в эту функцию вконце концов выполняется только в главном потоке, а пока она там выполняется, твой тредик тупо курит в сторонке. Реализована она на мой взгляд топорно - применимо в любом месте треда и в любой задаче, но за счет нехилой потери производительности и потери многопоточности во время ее работы. Я уж не говорю о последствиях зависания какого-либо треда в этой функции. далеко не во всех задачах нужен такой функционал.
её аналог можно легко реализовать самому, причем с учетом конкретной задачи, а следовательно сделать ее более эфективной и безопасной.

Посредством CreateThread ну никак не получается использовать веб-сервис в потоке Плачущий
Поток запускается, об этом говорит успешный вывод строки в Мемо из потока, а дальше никак.
Как быть и что делать?
Исходник прилагаю.
« Последнее редактирование: 21 декабря 2011, 16:58:44 от Nikita » Записан
Leex
Участник
**

Сказали спасибо: +132/-1
Offline Offline

Сообщений: 577


« Ответ #25 : 21 декабря 2011, 10:28:49 »

И не будет, т.к правило что нельзя обращаться к VCL из потоков никто не отменял.
Так делать из потока не лельзя:
Код
Form1->Memo1->Lines->Add("Отправка запроса на вход в систему");
Такое тоже небезопасно:
Код
login_request->username=Form1->LabeledEdit1->Text; 

Пример как корректно можно работать с VCL из потоков без Synchronise я приводил в ветке
http://cbuilder.ru/index.php/topic,8284.0.html
Отличае от Synchronise в том, что поток не ждет когда произойдёт перерисовка, т.е потоки работают асинхронно.

Записан
volvo877
Глобальный модератор
***

Сказали спасибо: +736/-1
Offline Offline

Сообщений: 891


« Ответ #26 : 21 декабря 2011, 10:57:06 »

Цитировать
Пример как корректно можно работать с VCL из потоков без Synchronise я приводил в ветке
Тот пример, кстати, не вполне корректен. Он будет работать, но до поры-до времени. Потом работать перестанет. На forums.embarcadero.com на этом обжигались не раз: свойство Handle класса TWinControl (от которого наследуется и форма) - НЕпотокобезопасно, и не гарантируется, что оно будет постоянным. В исходниках VCL можешь посмотреть, сколько раз вызывается TWinControl.RecreateWnd(), каждый раз хендл контрола будет меняться, соответственно, PostMessage будет уходить в никуда. Причем RecreateWnd() вызывается иногда даже при установке некоторых свойств формы (у меня сейчас нет исходников VCL, я просто помню одно из обсуждений), так что сказать "я не вызываю RecreateWnd, значит, мой код будет работать как положено" тоже нельзя.
Записан
gumi250
Участник
**

Сказали спасибо: +33/-1
Offline Offline

Сообщений: 254


« Ответ #27 : 21 декабря 2011, 11:45:15 »

Цитировать
Тот пример, кстати, не вполне корректен. Он будет работать, но до поры-до времени. Потом работать перестанет.
..
каждый раз хендл контрола будет меняться, соответственно, PostMessage будет уходить в никуда.
Чего то я не понял. В том примере было так:
Код:
PostMessageA(Form1->Handle,AM_UPDATELABEL,(DWORD)Form1->Label1,(DWORD)buf); 
Ну поменяется Handle у Form1, и что, он каждый раз для PostMessageA актуальный берется.


А еще такой вопрос. VCL это Visual Component Library. Класс _di_BFGlobalService используемый Никитой я не нашел на панелти визуальных компонентов, допускаю, что там не все классы. Но тот же класс Graphics::TBitmap я всегда считал классом VCL, но насколько я с ним сталкивался он хорошо работает в потоке. Вопрос: Все ли классы VCL не держат потоки? Если частично, то как узнать какие держат а какие нет?

Записан
volvo877
Глобальный модератор
***

Сказали спасибо: +736/-1
Offline Offline

Сообщений: 891


« Ответ #28 : 21 декабря 2011, 12:07:21 »

Цитировать
Ну поменяется Handle у Form1, и что
И ничего, если поменяется ДО отсылки и возьмется новый. А если поменяется в момент отсылки? Нет, если тебе "чтоб хоть как-то работало", оно конечно будет работать, вероятность сбоя мала. Только вот у меня специфика работы такая, что эта крайне малая вероятность сбоя может повлечь крайне негативные последствия, поэтому привычка: если что-то может сбойнуть - это не используется. Я просто предупредил...
Записан
Leex
Участник
**

Сказали спасибо: +132/-1
Offline Offline

Сообщений: 577


« Ответ #29 : 21 декабря 2011, 12:32:16 »

Какой ужос  Шокирован
Чем больше узнаешь билдер тем больше разочарований.
Но выход всё равно есть.
Отсылать сообщения можно и с помощью PostThreadMessage. Треды-то надо думать он не пересоздаёт  Подмигивающий
Так даже проще получится - нужно будет выкинуть
Код
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(AM_UPDATELABEL, TMessage, onUpdateLabelFromThread)
END_MESSAGE_MAP(TForm)

и назначить обработчик TApplication::OnMessage и уже там ловить свое сообщение
Записан
Страниц: [1] 2 3   Вверх
  Печать  
 
Перейти в: