![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Synchronize
3APA3A © (2004-07-04 00:29:00)Что делает Synchronize? Я использую его и в общих чертах представляю что этот метод делает, но мне этого мало...
Тимохов (2004-07-14 11:18:00) [1]
> Ihor Osov'yak © (14.07.04 04:05) [48]
> Да, еще. И в большинстве случаев после просветления исчезает
> желание использовать синхронайз..
я его тоже перестал использовать, т.к. часто нужно сделать "синхронайз" не в гралный поток, а в другой. А для этого приходится писать свою реализацию. А если есть реализация сделать "синхронайз" в любой поток, то почему бы ее не спользовать и для главного потока, а на метод synchronize вообще забить.
Ihor Osov'yak (2004-07-14 04:09:00) [2]сори, или что то с клиентом случилось, или со мной, вытащил на верх ветку двухнедельной давности :-(.
Ihor Osov'yak (2004-07-14 04:05:00) [3]моих две копейки. Мне кажется, синхронайз далеко не самое лучшее изобретение Борланда. Не раз приходилось наблюдать, как человек вмесо того, чтобы немного разобраться с sendmessage, postmessage, немного с обьектами синхронизации, начинал делать шаманские танцы вокруг синхронайз.. Причем, совсем не имея понятия, как это дело работает.. Причем на танцы идет много больще времени, чем собственно нужно для просветления в вопросах вокруг send и postmessage.
Да, еще. И в большинстве случаев после просветления исчезает желание использовать синхронайз..
y-soft (2004-07-06 15:23:00) [4]>Mim1 © (06.07.04 08:10) [46]
Я конечно извиняюсь, а кто будет вызывать этот метод?
Вызывать его будет функция инструментального потока для того, чтобы просто уведомить поток GUI, что он должен выполнить какой-то метод в удобное для потока GUI время. Т.е. сделать то же, что делает Synchronize, но не дожидаясь, когда метод начнет выполняться
Фактически этот ASyncronize будет просто вызывать PostMessage, передавая в одном из параметров указатель на какой-то внешний метод и сразу же возвращать управление. В этом и весь смысл - не заставлять инструментальный поток ждать, когда это не нужно.
Насчет ограничений. В VCL и вообще в Windows существует их множество, но они как-то не мешают жить программисту. Теоретически ведь можно много чего сделать такого, что не приведет ни к чему хорошему и без всяких Asinchronize :)
Вы ведь наверняка не вызываете в конструкторе объекта его деструктор? И не делаете перерисовку TControl, если не назначен Parent? :)
К тому же я собираюсь написать не какой-то новый потомок TThread, а класс-оболочку для удобной работы сразу со множеством потоков (скорее всего наследую его от TWinControl, чтобы не надо было подменять оконную функцию главного окна). Причем прямого доступа у программиста к ним не будет, только через методы и свойства контейнера-родителя. Вместо виртуального Execute у каждого элемента (это будут потомки TCollectionItem) будет событие OnExecute, в котором Вы и будете вызывать по мере необходимости Synchronize и ASynchronize. Написанный в этом событии код и будет выполняться в функции потока. Заодно и поправлю недостаток TThread при работе с исключениями в функции потока...
Т.е. есть желание написать удобный компонент-оболочку для комфортной "визуальной" работы с потоками при написании VCL приложений. Кидаете его на форму, прямо в IDE содаете сколько надо потоков, назначаете им обработчики и все! И не более того :) IMHO для Delphi такой подход более естественен, чем написание каждый раз классов-потомков...
Mim1 (2004-07-06 08:10:00) [5]
> [45] y-soft © (05.07.04 20:12)
Я конечно извиняюсь, а кто будет вызывать этот метод? да и вообще кому нужен метод в котором вы не можете обратится к полям обьекта, или метод для вызова которго нужно создать новый обьект.
> Время будет - может напишу и выложу :)
Лучше не тратьте его зря.
y-soft (2004-07-05 20:12:00) [6]>Mim1 © (05.07.04 16:44) [44]
Лучше пользуйтесь PostMessage.
А я обычно и пользуюсь :)
Хотя думал что-то над этой веткой и в принципе решил, что написать класс с Asynchronyze вполне смог бы... Время будет - может напишу и выложу :)
Mim1 (2004-07-05 16:44:00) [7]
> [38] y-soft © (05.07.04 14:03)
Вот по этому его и не сделали. Можно сделать но с кучей оговорок и т.д. Лучше пользуйтесь PostMessage.
Тимохов (2004-07-05 16:17:00) [8]
> Григорьев Антон © (05.07.04 15:06) [41]
да понял я - уже прочел.
виноват - поспешил с соображением :))))
Serginio666 (2004-07-05 15:29:00) [9]В D7 реагирует на SetEvent
procedure SignalSyncEvent;
{$IF Defined(LINUX)}
const
Dummy: Byte = 0;
var
nRead: Integer;
{$IFEND}
begin
{$IF Defined(MSWINDOWS)}
SetEvent(SyncEvent);
{$ELSEIF Defined(LINUX)}
if (ioctl(SyncEvent.ReadDes, FIONREAD, @nRead) = 0) and (nRead = 0) then
__write(SyncEvent.WriteDes, Dummy, SizeOf(Dummy));
{$IFEND}
end;
В procedure TApplication.WndProc(var Message: TMessage);
реагирует на сообщение
WM_NULL:
CheckSynchronize;
и соответственно в CheckSynchronize снимает событие и выполняет нужный метод
Григорьев Антон (2004-07-05 15:06:00) [10]
> Тимохов © (05.07.04 14:58) [40]
>
> > Тимохов © (05.07.04 14:56) [39]
>
> да... я конечно очень оригнален со своим замечанием :)))))
А я не буду оригинален с ответом: см. [19]. Я ведь до сих пор на пятёрке сижу.
Тимохов (2004-07-05 14:58:00) [11]
> Тимохов © (05.07.04 14:56) [39]
да... я конечно очень оригнален со своим замечанием :)))))
Тимохов (2004-07-05 14:56:00) [12]
> Григорьев Антон © (04.07.04 07:02) [6]
прошу прощения - может где то выше уже было: нет вермени читать.
synchronioze юзает postmessage (в д6).
по сути работает все же как send - реализовано через post + waitforsingleobject (некий ивент)
y-soft (2004-07-05 14:03:00) [13]>Григорьев Антон © (05.07.04 13:37) [36]
(продолжение)
Пример для Synchronize привожу только потому, что в гипотетическом ASynchronize в качестве параметра передается точно такой же TThreadMethod (который procedure of object).
Это может быть метод любого объекта, кроме вызывающего TThread
y-soft (2004-07-05 13:51:00) [14]>Григорьев Антон © (05.07.04 13:37) [36]
См. [34]. И вообще: кто и где сказал, что это непременно должен быть метод вызывающего потока?
Вот все, что сказано в Help:
TThread.Synchronize
type TThreadMethod = procedure of object;
procedure Synchronize(Method: TThreadMethod);
Description
Synchronize causes the call specified by Method to be executed using the main VCL thread, thereby avoiding multi-thread conflicts. If you are unsure whether a method call is thread-safe, call it from within the main VCL thread by passing it to the Synchronize method.
Execution of the thread is suspended while Method is executing in the main VCL thread.
Note: You can also protect unsafe methods using critical sections or the multi-read exclusive-write synchronizer.
Григорьев Антон (2004-07-05 13:37:00) [15]
> y-soft © (05.07.04 11:53) [32]
> >Mim1 © (05.07.04 11:45) [31]
>
> Ну и пусть умер. Какая разница, если Asynchronize всего-навсего
> ставит сообщение в очередь. Или устанавливает событие. Или
> безопасно изменяет общие данные. Когда придет очередь, поток-приемник
> вызовет свой обработчик, а не обработчик потока-источника
А внутри метода, который используется в Asynchronize, есть доступ к полям TThread'а. А поток-то уже умер, объект нити уничтожен. Всё, AV.
default (2004-07-05 12:26:00) [16]jack128 © (05.07.04 12:00) [33]
"Инструментальному потоку в приведенном примере совсем без разницы, когда и как поток GUI будет выполнять визуализацию"в таком случае это как говорится и козе понятно
y-soft (2004-07-05 12:04:00) [17]>jack128 © (05.07.04 12:00) [33]
PostMessage в поток VCL. И не дожидаться обработки этого сообщения..
В общем-то так чаще всего и делают. В параметрах сообщения можно передавать указатель на метод. Естественно, это не должен быть метод вызывающего потока, а то может получиться, как в [31] :)
jack128 (2004-07-05 12:00:00) [18]
> тогда как будет работать Asynchronize(
PostMessage в поток VCL. И не дожидаться обработки этого сообщения..
и вообще - зачем искуственно тормозить инструментальный поток синхронизацией?
y-soft (2004-07-05 11:53:00) [19]>Mim1 © (05.07.04 11:45) [31]
Ну и пусть умер. Какая разница, если Asynchronize всего-навсего ставит сообщение в очередь. Или устанавливает событие. Или безопасно изменяет общие данные. Когда придет очередь, поток-приемник вызовет свой обработчик, а не обработчик потока-источника
Mim1 (2004-07-05 11:45:00) [20][28] jack128 © (05.07.04 11:34)
Ага, поток уже умер, а тут подошла очередь и начал выполняться asyncronize. :)