|
How to run FoxPro EXE-server asynchronously. Eurika!
|
|||
---|---|---|---|
#18+
And have it send events and callback. Two demo .PRG files presented. ... |
|||
:
Нравится:
Не нравится:
|
|||
09.03.2013, 19:41 |
|
How to run FoxPro EXE-server asynchronously. Eurika!
|
|||
---|---|---|---|
#18+
Шедевр Код: vbnet 1.
Еще Семафоры для синхронизации расплодившихся процессов, и проверка на время исполнения по таймату, а то через 2 часа - мне эти самые данные уже могут быть и не нужны. ... |
|||
:
Нравится:
Не нравится:
|
|||
09.03.2013, 21:00 |
|
How to run FoxPro EXE-server asynchronously. Eurika!
|
|||
---|---|---|---|
#18+
Rostislav D. Kudryashov Мне кажется, что код можно немного упростить, объединив в один класс AsyncWorker с классом Worker, класс BackCaller с классом Recipient. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.03.2013, 10:08 |
|
How to run FoxPro EXE-server asynchronously. Eurika!
|
|||
---|---|---|---|
#18+
В этом форуме по-русски принято общаться ... |
|||
:
Нравится:
Не нравится:
|
|||
10.03.2013, 11:14 |
|
How to run FoxPro EXE-server asynchronously. Eurika!
|
|||
---|---|---|---|
#18+
Dima TВ этом форуме по-русски принято общаться Соду по мылу ТС - ему не обязательно Ну если ТС силен в аглицком ему только на http://www.universalthread.com/ там его оценят. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.03.2013, 15:53 |
|
How to run FoxPro EXE-server asynchronously. Eurika!
|
|||
---|---|---|---|
#18+
sg12, боюсь, ты сам не пробовал воспользоваться этой идеей. А у меня при переносе метода WorkIt из класса Worker на уровень выше в AsyncServer этот метод не хочет вовремя остановиться и выдаёт сообщение, что куда-то пропал его любимый элемент THIS.BackCaller_o. Ребята, вы как-нибудь поответственнее к своим словам. Ведь вы все - профессионалы. Но если уж о чём я жалею, это важный момент реализации DCOM-сервера, который надо бы отразить даже в демонстрашке. Чтоб сервер не захватывал всю память, надо непременно в его метод Init вставить SYS(3050,1,10000000) - ограничить аппетит 10 мегобайтами. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.03.2013, 16:31 |
|
How to run FoxPro EXE-server asynchronously. Eurika!
|
|||
---|---|---|---|
#18+
sg12, хоть твоё предложение и невпопад, но спасибо, что моя попытка его реализации натолкнула меня на важную подробность. Если метод WorkIt в верхнем классе AsyncServer, то после выполнения AsyncServer.Destroy управление переходит к неуспевшему остановиться AsyncServer.WorkIt. Это чревато неприятностями, даже если из AsyncServer.Destroy запущено аккуратное закрытие выполняемого задания. Чтобы избежать возобновления работы AsyncServer.WorkIt надо или вставлять в него специально для этого случая какое-то ON ERROR, или просто держать этот метод в отдельном классе, как у меня и сделано. Ведь ON ERROR в WorkIt для персечения его работы это, во-первыхи, извращение, а во-вторых - всё равно всё равно WorkIt останавливается не вовремя. А если после AsyncServer.Destroy запустится Worker.Destroy, то Worker.WorkIt уже не включится. - Хотя, это я сейчас проверю. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.03.2013, 17:05 |
|
How to run FoxPro EXE-server asynchronously. Eurika!
|
|||
---|---|---|---|
#18+
Rostislav D. Kudryashov Не совсем понятно, что не останавливается. Надо ведь из Worker все перенести в AsyncWorker, все его свойства, а вместо строки THIS.oWorker = CREATEOBJECT('Worker',m.toBackCaller) вставить из INIT строку THIS.oBackCaller = m.toBackCaller Тогда в промежуточном классе Worker отпадет необходимость, в нем ведь нет ничего другого, все будет сидеть в AsyncWorker. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.03.2013, 17:10 |
|
How to run FoxPro EXE-server asynchronously. Eurika!
|
|||
---|---|---|---|
#18+
sg12, вместо того, чтоб давать объяснения для дураков, как им ноги переставлять, лучше пришли работающий код. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.03.2013, 17:18 |
|
How to run FoxPro EXE-server asynchronously. Eurika!
|
|||
---|---|---|---|
#18+
Пошел за попкорном, жду очередного срача в продолжение темы "Общие принципы построения приложения в FoxPro " ЗЫ Модеру на заметку Серега, тебе тут спокойно не будет ... |
|||
:
Нравится:
Не нравится:
|
|||
10.03.2013, 17:32 |
|
How to run FoxPro EXE-server asynchronously. Eurika!
|
|||
---|---|---|---|
#18+
Rostislav D. Kudryashov Работать будет или нет - вы уж сами проверяйте, ваш же код. Обработку ошибок в любом случае надо делать, у вас вызов в цикле без выхода из него. DEFINE CLASS AsyncWorker as Custom OLEPUBLIC oStarter = NULL tWorkTime = DATETIME() lStopFlag = .T. oBackCaller = NULL PROCEDURE StartAsync(m.toBackCaller) IF ISNULL(THIS.oStarter) THIS.oBackCaller = m.toBackCaller THIS.oStarter = CREATEOBJECT('Starter') ELSE IF THIS.lStopFlag THIS.oStarter.INTERVAL = 1000 ENDIF ENDIF PROCEDURE StopIt() THIS.lStopFlag = .T. FUNCTION GetWorkTime () RETURN THIS.tWorkTime PROCEDURE WorkIt() THIS.lStopFlag = .F. DO WHILE !THIS.lStopFlag IF DATETIME() > THIS.tWorkTime + 5 THIS.tWorkTime = DATETIME() THIS.oBackCaller.DoCallBack(JUSTSTEM(_VFP.SERVERNAME),TIME()) ENDIF ENDDO PROCEDURE Destroy THIS.StopIt() ENDDEFINE piva. Хотите - заведите тему, подтыркивать некрасиво. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.03.2013, 18:11 |
|
How to run FoxPro EXE-server asynchronously. Eurika!
|
|||
---|---|---|---|
#18+
pivaПошел за попкорном, жду очередного срача в продолжение темы "Общие принципы построения приложения в FoxPro " Модератор: Пока нарушений правил форума нет. Весна всегда была трудным периодом. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.03.2013, 18:14 |
|
How to run FoxPro EXE-server asynchronously. Eurika!
|
|||
---|---|---|---|
#18+
Докладываю факты. В конец AsyncServer.Destroy, Worker.Destroy, Starter.Timer и Worker.WorkIt вставлена выдача в текстовый файл времени выхода из этих методов. 18:07:50 WorkIt Fini -- Первая интерактивная остановка 18:07:50 Starter.Timer 18:08:13 AsyncServer.Destroy -- Обнуление объекта сервера в приложении клиента 18:08:13 WorkIt Fini 18:08:13 Starter.Timer 18:08:13 Worker.Destroy Если же в AsyncServer.Destroy не сбрасывать флаг Worker.StopFlag_l, то из-за того, что предотвратить возврат управления в прерванный Worker.WorkIt из AsyncServer.Destroy невозможно, то не завершённый Worker.WorkIt не даст закрыться COM-серверу - он продолжит занимать память без использования ЦПУ. А вот если поместить WorkIt в AsyncServer, то нормальное завершение этого метода по сбросу флага StopFlag_l уже невозможно, т.к. после выполнения AsyncServer.Destroy этот класс уже не сохраняет условий для выполнения других своих методов. Ещё раз спасибо коллеге sg12, что он обратил моё внимание на этот скользкий момент прерывания работы запущенного метода. В классе Worker обязательно должен быть метод Destroy! Но простите меня, выставлять исправленный код я уж не буду. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.03.2013, 18:27 |
|
How to run FoxPro EXE-server asynchronously. Eurika!
|
|||
---|---|---|---|
#18+
Пожалуй, я погорячился. Ведь "насильственно" прекратить работу метода WorkIt у нас нет фоксовских средств. Т.е. если WorkIt усмотрит через какое-то время после срабатывания AsyncServer.Destroy флаг экстренной остановки StopIt, то этот флаг и послужит ему сигналом аккуратного заметания следов незаконченной работы. И метод Worker.Destroy для этой цели не нужен. А чтоб мой демонстратор был пореалистичнее, в нём надо дать возможность штатного завершения методу WorkIt - например, по интервалу времени. Пожалуй, повторю выкладку скорректированной редакции. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.03.2013, 18:43 |
|
How to run FoxPro EXE-server asynchronously. Eurika!
|
|||
---|---|---|---|
#18+
sg12, тебе "непонятно" (10.03.2013 17:10, 14031939), а ты бы подумал, почему первые два запуска перемещённый по твоему рецепту метод AsyncServer.WorkIt работает без запинки, а после срабатывания AsyncServer.Destroy - уже не может. Как же, по-твоему, этот метод работал "до того", если я, по твоему предположению, понаделал каких-то ошибок в реализации твоего "мудрого" совета? Стыдно лепить в ленту нафантазированные предположения! ... |
|||
:
Нравится:
Не нравится:
|
|||
10.03.2013, 18:54 |
|
How to run FoxPro EXE-server asynchronously. Eurika!
|
|||
---|---|---|---|
#18+
Rostislav D. Kudryashov По моему, в Workit лучше обрабатывать возврат, чем работать через его сомнительное зависание. Что-то вроде: llSuccess = THIS.oBackCaller.DoCallBack() IF llSuccess ... Или где-то создавать еще одно свойство, что-то вроде .lSuccess Второй код PROCEDURE RunAsyncServer LPARAMETERS m.tcServerName m.tcServerName = IIF(EMPTY (m.tcServerName),'LocalHost',tcServerName) LOCAL m.loBac, m.lnBind, m.loAsy, m.lcMsg m.loBac = CREATEOBJECT('BackCaller') m.lnBind = BINDEVENT(m.loBac,'cCurTime',m.loBac,'HandleIt') И т.д. DEFINE CLASS BackCaller AS Session oRecipient = NULL cCurTime = '' PROCEDURE Init(m.toRecipient) THIS.oRecipient = m.toRecipient PROCEDURE DoCallBack(m.tcSender, m.tcTime) LOCAL m.lnCnt, m.ltDT FOR m.lnCnt = 1 TO 3 m.ltDT = DATETIME() DO WHILE DATETIME() < m.ltDT + 1 ENDDO THIS.cCurTime = m.tcTime THIS.AcceptIt('From ' + m.tcSender + ' ' + m.tcTime) ENDFOR PROCEDURE AcceptIt (m.tcMessage) ? 'AcceptIt ' + m.tcMessage PROCEDURE HandleIt () LOCAL m.Ev_la[1] AEVENTS(m.laEv,0) ? 'HandleIt ' + m.laEv[1].NAME + '.' + m.laEv[2] + ' ' + TRANSFORM(m.laEv[2]) ENDDEFINE && BackCaller ... |
|||
:
Нравится:
Не нравится:
|
|||
10.03.2013, 18:57 |
|
How to run FoxPro EXE-server asynchronously. Eurika!
|
|||
---|---|---|---|
#18+
Rostislav D. Kudryashov Код: sql 1. 2. 3.
Стандартная ошибка при работе с таймерами. Типа мы его остановили и он обязан остановиться, на самом деле обязан больше не срабатывать. Но если он уже успел несколько раз сработать, а запуска метода Timer() по этим сработкам не произошло, то произойдет и этот код отработает несколько раз. Может несколько раз сработать. Добавь в начале: Код: sql 1. 2. 3.
PS Удобнее останавливать Timer.Enabled = .F., т.к. Interval не меняется и не надо задавать его в куче мест для повторного запуска. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.03.2013, 18:57 |
|
How to run FoxPro EXE-server asynchronously. Eurika!
|
|||
---|---|---|---|
#18+
Rostislav D. Kudryashovто не завершённый Worker.WorkIt не даст закрыться COM-серверу - он продолжит занимать память без использования ЦПУ. Это уже ошибка - один объект держит другой объект, может дойти и до трех пальцев. Ошибки должны обрабатываться программно. Как и закрытие открытых объектов. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.03.2013, 19:08 |
|
How to run FoxPro EXE-server asynchronously. Eurika!
|
|||
---|---|---|---|
#18+
Ну и Timer.Interval = 1000 это тормоз. Ждем секунду чтобы начать? Зачем? Надо чтоб работало при Timer.Interval = 1 ... |
|||
:
Нравится:
Не нравится:
|
|||
10.03.2013, 19:10 |
|
How to run FoxPro EXE-server asynchronously. Eurika!
|
|||
---|---|---|---|
#18+
Dima T, а ведь это ты гонишь какое-то духовидство. Запускаем программу TestTimer.PRG и смотрим её выдачу TestTimer.LOG. Реальными фактами твои предположения не подтверждаются, значит - нафантазировал. Ай-я-яй. TestTimer.PRG SET TEXTMERGE ON SET TEXTMERGE TO TestTimer.LOG Timer_lo = NEWOBJECT ('MyTimer') GETFILE() && We'll have a walk, while MyTimer's working \ <<TIME()>> Basta SET TEXTMERGE TO SET TEXTMERGE OFF ***************************** DEFINE CLASS MyTimer AS Timer Interval = 2000 Enabled = .T. PROCEDURE Timer \ <<TIME()>> <<PROGRAM()>> THIS.Interval = 0 ENDPROC && MyTimer.Timer ENDDEFINE && MyTimer TestTimer.LOG 19:21:17 MYTIMER.TIMER 19:21:32 Basta ... |
|||
:
Нравится:
Не нравится:
|
|||
10.03.2013, 19:27 |
|
How to run FoxPro EXE-server asynchronously. Eurika!
|
|||
---|---|---|---|
#18+
Rostislav D. KudryashovDima T, а ведь это ты гонишь Не хочу ничего доказывать, наступишь на эти грабли, сам поймешь о чем я писал. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.03.2013, 19:33 |
|
How to run FoxPro EXE-server asynchronously. Eurika!
|
|||
---|---|---|---|
#18+
Dima T, Для большей наглядности и доказательности. Нет такой стандартной ошибки, есть у твоя стандартная выдумка - не лезть за словом ни в карман, ни в эксперимент. Духовидство, или проще, застарелые предрассудки TestTimer.PRG SET TEXTMERGE ON SET TEXTMERGE TO TestTimer.LOG \ <<TIME()>> Starting Timer_lo = NEWOBJECT ('MyTimer') GETFILE() && We'll have a walk, while MyTimer's working \ <<TIME()>> Basta SET TEXTMERGE TO SET TEXTMERGE OFF ***************************** DEFINE CLASS MyTimer AS Timer Interval = 2000 Enabled = .T. PROCEDURE Timer \ <<TIME()>> <<PROGRAM()>> THIS.Interval = 0 m.t0 = SECONDS() DO WHILE SECONDS() < m.t0 + 10 ENDDO \ <<TIME()>> After 10 seconds ENDPROC && MyTimer.Timer ENDDEFINE && MyTimer TestTimer.LOG 19:36:18 Starting 19:36:20 MYTIMER.TIMER 19:36:30 After 10 seconds 19:36:44 Basta ... |
|||
:
Нравится:
Не нравится:
|
|||
10.03.2013, 19:41 |
|
How to run FoxPro EXE-server asynchronously. Eurika!
|
|||
---|---|---|---|
#18+
Запусти этот код Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17.
... |
|||
:
Нравится:
Не нравится:
|
|||
10.03.2013, 19:44 |
|
How to run FoxPro EXE-server asynchronously. Eurika!
|
|||
---|---|---|---|
#18+
Итак, в эксперименте родилось новое знание, недоступное ранее без влезания в "асинхронность". После срабатывания метода Class.Destory никакому другому методу на этаже этого класса уже работать не позволено. А вот для Member-классов, такая возможность предоставлена - их методы Destroy вызываются последовательно по цепочке вложенности Member-ship. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.03.2013, 19:47 |
|
How to run FoxPro EXE-server asynchronously. Eurika!
|
|||
---|---|---|---|
#18+
Dima T, этот пример надуманный, к делу не относится. Значение Interval = 1 - одна милли-секунда - это погрешность срабатывания таймера. Использовать такие значения - просто техническая неграмотность. В моём примере с AsyncServer значение Starter.Interval = 1000 - 1 cек, реалистично. Так твои фокусы тебя не спасают, и sg12 - тоже. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.03.2013, 19:58 |
|
How to run FoxPro EXE-server asynchronously. Eurika!
|
|||
---|---|---|---|
#18+
Rostislav D. KudryashovЧтобы избежать возобновления работы AsyncServer.WorkIt надо или вставлять в него специально для этого случая какое-то ON ERROR, или просто держать этот метод в отдельном классе, как у меня и сделано. Ведь ON ERROR в WorkIt для персечения его работы это, во-первыхи, извращение, а во-вторых - всё равно всё равно WorkIt останавливается не вовремя. Кроме ON ERROR есть еще COMRETURNERROR() и TRY ... ENDTRY, но это вы уж сами. Из Destroy обычно вызывается процедура закрытия программы, как и из обработчика ошибок, OnShutdown и др. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.03.2013, 20:03 |
|
How to run FoxPro EXE-server asynchronously. Eurika!
|
|||
---|---|---|---|
#18+
Rostislav D. Kudryashovодна милли-секунда - это погрешность срабатывания таймера. Сам то понял что написал? таймер это не аналоговый прибор с погрешностями. Кстати одна миллисекунда это очень много времени. Слабенький процессор в 1,5 ГГц выполняет до 1,5 млн. операций за это время. Rostislav D. KudryashovИспользовать такие значения - просто техническая неграмотность. Быстро работающий код это неграмотность. Забавно. Желаю удачи в написании тормозов. Будет глючить - увеличь интервал ... |
|||
:
Нравится:
Не нравится:
|
|||
10.03.2013, 20:07 |
|
How to run FoxPro EXE-server asynchronously. Eurika!
|
|||
---|---|---|---|
#18+
Dima T, a prpos на твой PS авторPS Удобнее останавливать Timer.Enabled = .F. На моём компе, если запустить Timer с Interval < 38 и при первом срабатывании в методе Timer поставить THIS.Interval = 0, то и установка THIS.Enabled = .F. не спасает от серии последующих срабатываний таймера. Похоже, это результат разности между скоростью реализации таймера средствами WinAPI и скоростью интерпретации операторов FoxPro. Пока FoxPro перешагнёт одну строку, WinAPI крутанёт таймер несколько десятков раз. Так что рекомендованный тобой "замок" по свойствам Timer на входе самое верное. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.03.2013, 22:50 |
|
How to run FoxPro EXE-server asynchronously. Eurika!
|
|||
---|---|---|---|
#18+
Dima T, a prpos на твой PS Dima TPS Удобнее останавливать Timer.Enabled = .F. На моём компе, если запустить Timer с Interval < 38 и при первом срабатывании в методе Timer поставить THIS.Interval = 0, то и установка THIS.Enabled = .F. не спасает от серии последующих срабатываний таймера. Похоже, это результат разности между скоростью реализации таймера средствами WinAPI и скоростью интерпретации операторов FoxPro. Пока FoxPro перешагнёт одну строку, WinAPI крутанёт таймер несколько десятков раз. Так что рекомендованный тобой "замок" по свойствам Timer на входе самое верное. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.03.2013, 22:52 |
|
How to run FoxPro EXE-server asynchronously. Eurika!
|
|||
---|---|---|---|
#18+
sg12, ну вот ты пытаешься хоть к чему-то прицепить свои "опровержения", а ведь речь о том, что ты не раскаялся в своём предложении поднять метод WorkIt из Member-класса Worker в контейнер для этого класса - класс AsyncWorker. Криминал в твоём предложении тот, что если AsyncWorker.Destroy сработает во время работы метода WorkIt, то этот метод всё равно получит управление сразу после выхода из AsyncWorker.Destroy. Но все члены класса AsyncWorker для метода WorkIt станут недоступны. Так что если WorkIt оказался в классе AsyncWorker, то неизбежен сбой при обращении из WorkIt к членам AsyncWorker. Пока не осознаешь свою ошибку, больше сюда не пиши. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.03.2013, 23:14 |
|
How to run FoxPro EXE-server asynchronously. Eurika!
|
|||
---|---|---|---|
#18+
Еще нужно обязательно делать маппинг таблиц на память, перед использованием. Create, так сказать, FileMappingDBF и т.д.. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.03.2013, 23:18 |
|
How to run FoxPro EXE-server asynchronously. Eurika!
|
|||
---|---|---|---|
#18+
Rostislav D. KudryashovDima T, a prpos на твой PS авторPS Удобнее останавливать Timer.Enabled = .F. На моём компе, если запустить Timer с Interval < 38 и при первом срабатывании в методе Timer поставить THIS.Interval = 0, то и установка THIS.Enabled = .F. не спасает от серии последующих срабатываний таймера. Похоже, это результат разности между скоростью реализации таймера средствами WinAPI и скоростью интерпретации операторов FoxPro. Пока FoxPro перешагнёт одну строку, WinAPI крутанёт таймер несколько десятков раз. Так что рекомендованный тобой "замок" по свойствам Timer на входе самое верное. Я и не говорил что Enabled = .F. спасет от повторов. От повторов спасет только проверка что таймер уже остановлен. Пример выше я давал. Enabled = .F. только упрощает код. Например у тебя несколько мест где прописано .Interval = 1000, если ты 1000 захочешь сменить - надо будет выискивать все места. При использовании Enabled интервал будет указан только в одном месте. Что касается твоих догадок, то Interval < 38 частный случай для конкретного кода на конкретном компе. Может быть больше, может меньше. Если бы была рекомендуемая константа - написали бы в хэлпе. В твоем случае таймер только для организации асинхронности и никаких доп.пауз не требуется, значит ему надо Interval = 1 чтобы полезный код начал выполняться как можно быстрее. Причина в следующем: Timer при включении дает команду виндовсу ( SetTimer() ) слать окну фокса сообщение WM_TIMER, которое с заданной периодичностью добавляется в очередь сообщений и обрабатывается по мере возможности, т.е. в момент остановки таких сообщений может быть несколько и они все будут обработаны фоксом. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.03.2013, 07:19 |
|
|
start [/forum/topic.php?all=1&fid=41&tid=1583124]: |
0ms |
get settings: |
10ms |
get forum list: |
15ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
41ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
62ms |
get tp. blocked users: |
2ms |
others: | 13ms |
total: | 166ms |
0 / 0 |