-
При использовании таймера из модуля MMSystem, в котором идёт вывод битмапа, через некоторое время происходит коллапс. Т.е. если потаскать форму или изменять её размеры рисование битмапа не происходит.
Вот примерный код:
var bmp:TBitmap; TimerSpectrId:UINT;
procedure Timer(uTimerlD, uMessage: UINT;dwUser, awl, dw2: DWORD);stdcall; begin bmp.Canvas.Brush.Color:=RGB(Random(256), Random(256), Random(256)); bmp.Canvas.Rectangle(0,0,100,100); Form1.Canvas.Draw(0,0,bmp); end;
procedure TForm1.FormCreate(Sender: TObject); begin bmp:=TBitmap.Create; bmp.Width:=100; bmp.Height:=100;
TimerSpectrId:=timeSetEvent(50, 1, @Timer, 0, TIME_PERIODIC); end;
-
Переименуй Timer, скажем в _Tmr0001, т.к. это там в ВЦЛ чего-то перекрывает, что возможно и является причиной.
-
> Efir © (06.09.07 14:54)
Мутьтимедийные таймеры работают в своих собственных дополнительных потоках, поэтому обращение к визуальным VCL-контролам в теле колбэк-процедуры Timer() недопустимо.
-
>Мутьтимедийные таймеры работают в своих собственных дополнительных потоках, поэтому обращение к визуальным VCL-контролам в теле колбэк-процедуры Timer() недопустимо.
Т.к. у Delphi нет средств, чтобы это проконтроллировать и пресечь, это вполне допустимо.
-
> у Delphi нет средств, чтобы это проконтроллировать
Да ты что ?! А мужики-то и не знают)
> и пресечь
Зачем пресекать-то ?
> это вполне допустимо
Угу. Только потом не надо при всем честнОм народе жаловаться на "глюки" и "коллапсы")
-
>Угу. Только потом не надо при всем честнОм народе жаловаться на "глюки" и "коллапсы")
Почему не надо? Надо. И требовать, чтобы потоки по-человечески сделали.
Про зачем пресекать по инерции спросил?
-
> требовать, чтобы потоки по-человечески сделали
Не понял... Кто у кого требовать должен ? И что значит "по-человечески" ?
> Про зачем пресекать по инерции спросил?
Нет не по инерции.
Зачем пресекать то что продумано разработчиком (в дан.случае разработчиками MS Windows) и очевидно ?
-
> Мутьтимедийные таймеры работают в своих собственных дополнительных > потоках, поэтому обращение к визуальным VCL-контролам в > теле колбэк-процедуры Timer() недопустимо.
Но тогда почему проблемы возникают именно с битмапом, который я трогаю только из потока. Проблема исчезает при использовании Lock, UnLock.
bmp.Canvas.Lock; bmp.Canvas.Brush.Color:=RGB(Random(256), Random(256), Random(256)); bmp.Canvas.Rectangle(0,0,100,100); Form1.Canvas.Draw(0,0,bmp); bmp.Canvas.UnLock;
-
> почему проблемы возникают именно с битмапом, который я трогаю > только из потока
Это не очевидно.
Зато очевидна засада в строчке
Form1.Canvas.Draw(0,0,bmp);
-
>Не понял... Кто у кого требовать должен ? И что значит "по-человечески" ?
Ты, я, Эфир, Дядя Фёдор, пёс и кот у КодеГеар. По-получеловечески значит хотя бы warning.
-
> у КодеГеар
Опять не понял)..
Что мы должны требовать у "КодеГеар" ? Чтобы он переделал функциональность timeSetEvent что ли ?
> хотя бы warning
Кто кого о чем должен предупреждать ?
-
>Сергей М. © (06.09.07 17:24) [10]
>TimerSpectrId:=timeSetEvent(50, 1, @Timer, 0, TIME_PERIODIC);
Вот здесь компилятор Delphi должен возопить, что callback будет выполняться в другом потоке, поэтому весь код в нём должен быть thread-safe.
-
> Сергей М. ©
Спасибо.
-
> sdubaruhnul (06.09.07 17:29) [11]
> здесь компилятор Delphi должен возопить, что callback будет > выполняться в другом потоке
С какого перепугу он должен "возопить" ?
Для компилятора ф-ция timeSetEvent - точно такая же как и сотни и тысячи других подпрограмм, генерацию кода вызова которых ты от него требуешь.
Компилятор знать не знает и знать не обязан о контексте работы вызванной подпрограммы, знать это положено нам как разработчикам прикладной логики. А знать это мы можем как минимум внимательно читая всякие мануалы и справки, где описывается логика работы той или иной интересующей нас п/программы.
Так что не городи уже чушь)
-
>Компилятор знать не знает и знать не обязан о контексте работы вызванной подпрограммы, знать это положено нам как разработчикам прикладной логики. А знать это мы можем как минимум внимательно читая всякие мануалы и справки, где описывается логика работы той или иной интересующей нас п/программы.
Если компилятор чего-то не знает, то он должен гарантировать безопасное выполнение кода в любом возможном случае.
Раз уж компилятор не знает, то среда должна предоставить безопасное решение таймера, пускай на основе того же MMSystem'ного таймера (TTimer не есть такое решение). С этим у Delphi вообще туго.
Так что не надо про чушь. Я читал много веток с твоим участием, про чушь ты любишь говорить. Так проще всего. Согласен, чуть-чуть дополнений ([7]) и всё работает и можно вроде бы не волноваться. Любые возражения - это чушь, потому что есть рабочий код. Пусть и в таком грязном стиле - функция API смешана с VCL. Но меня волнует стиль, и для меня это не чушь.
И не надо отсылать ко всяким мануалам. Разве oxfff не показал, что даже оператор присвоения недокументировано не thread-safe?
-
> Так что не городи уже чушь)
Двумя лапами поддержу. Чушь полнейшая. Среда ничего не обязана знать (да и не может), программист обязан перед использованием функции ознакомится с ее описанием в MSDN.
-
> Если компилятор чего-то не знает, то он должен гарантировать > безопасное выполнение кода в любом возможном случае
Ерунда полная. Пример ? Пожалуйста !
В BASM-блоке кода ты вправе такого нахреновертить, что мало не покажется не то что компилятору, а и самой ОС.
Вот как, скажи на милось, компилятор распознает опасность модификации того или иного сегментного регистра, если он сам дает тебе право его модифицировать, полагаясь на твои знания+разум и защищенность ОС от твоих неверных программных манипуляций ?
> среда должна предоставить безопасное решение таймера
Она и предоставляет. На основе того же TTimer. Но и с TTimer'oм при желании можно "наловить косяков".
Касаемо же подобного рода API-ф-ций среда полагается опять же на знания+разум программиста, предупреждая при этом о потоконебезопасности VCL.
-
>В BASM-блоке кода ты вправе такого нахреновертить, что мало не покажется не то что компилятору, а и самой ОС.
Мы говорим о языке Delphi или о BASM? Кажется, код из [0] был написан на Delphi. Кстати, об ассемблерных вставках недавно была ветка, где я выразил мнение о том, что их надо вообще запретить. Причина? Именно потому, что в ней "ты вправе такого нахреновертить, что мало не покажется не то что компилятору, а и самой ОС".
Теперь мой пример. Range checking. Или ты скажешь, что это тоже чушь? Что программист должен всегда проверять индекс в коде, а если пропустил, то искать непонятную AV? Кажется, есть такой язык - C - где проверки границ нет. И какова его область применения сейчас?
-
> [17] sdubaruhnul (07.09.07 12:11)
Плохая примета после грибочков писать на форуме. ^^
Запретить BASM? Ну извините, это мое дело, использовать его или нет. Если ты не в состоянии предугадать, какие неожиданности будут в результате выполнения того или иного кода - это твои проблемы как программиста, а не бедной среды, которая тебе так не угодила.
По поводу таймера. А если я напишу свой таймер, который будет выполняться в отдельном потоке, то как теперь несчастный компилятор должен выдавать предупреждения?
Вообще, ты и правда несешь чушь. Если что-то не получается сделать - это не повод тут же пинять на среду, компилятор и всех, под руку попавшхся.
> [0] Efir © (06.09.07 14:54)
Покопай в сторону синхронизации между потоками. Введи эти слова в поске и тут же найдешь много интересного.
-
>Запретить BASM? Ну извините, это мое дело, использовать его или нет. Если ты не в состоянии предугадать, какие неожиданности будут в результате выполнения того или иного кода - это твои проблемы как программиста, а не бедной среды, которая тебе так не угодила.
Очень показательно здесь слово "предугадать". Угадывай на здоровье.
Нафига нам BASM, об который спотыкается оптимизатор?
>По поводу таймера. А если я напишу свой таймер, который будет выполняться в отдельном потоке, то как теперь несчастный компилятор должен выдавать предупреждения?
Вот, в этом то весь вопрос. Ты не можешь себе представить, как это можешь быть осуществлено. Какие средства языка нужны для этого. Ты просто представляешь себе перед глазами работу потоков в Delphi и не понимаешь, куда там можно впихнуть проверку.
Просто для того, чтобы ты мог хоть немного пофантазировать, приведу простой пример из другого языка - Java. Если в каком-то методе может возникать исключение, то это указывается в объявлении метода после ключевого слова throws, и программа не откомпилируется, пока у этого исключения не будет обработчика.
Если ты удовлетворяешь требованиям, которые ты же с Сергеем М установил (про логическое мышление программиста), то сможешь расширить этот пример и до дельфийских потоков. И также вспомнишь, что подобные примеры есть даже в Делфи, причём довольно старые и успешные.
-
> [19] sdubaruhnul (07.09.07 21:43)
> Очень показательно здесь слово "предугадать". Угадывай на > здоровье.
И буду угадывать дальше, пока ты ждешь выхода "идеального компилятора".
> Нафига нам BASM, об который спотыкается оптимизатор?
А в чем был бы его смысл, если бы оптимизатор там не спотыкался?
> Вот, в этом то весь вопрос. Ты не можешь себе представить, > как это можешь быть осуществлено. Какие средства языка > нужны для этого.
Ты ошибаешься.
> Ты просто представляешь себе перед глазами работу потоков > в Delphi и не понимаешь, куда там можно впихнуть проверку.
Какую еще проверку? Вообще, противоречивое и бессмысленное высказывание.
> Просто для того, чтобы ты мог хоть немного пофантазировать, > приведу простой пример из другого языка - Java. Если в > каком-то методе может возникать исключение, то это указывается > в объявлении метода после ключевого слова throws, и программа > не откомпилируется, пока у этого исключения не будет обработчика.
Ну и к чему тут ты про это? Никакой связи не вижу.
> Если ты удовлетворяешь требованиям, которые ты же с Сергеем > М установил (про логическое мышление программиста), то сможешь > расширить этот пример и до дельфийских потоков. И также > вспомнишь, что подобные примеры есть даже в Делфи, причём > довольно старые и успешные.
У тебя больное воображение...
-
>Rial © (07.09.07 22:24) [20]
У тебя ушло 15 секунд на чтение и 20 на ответ. Пока не прекратишь бросаться отмазками и не начнёшь думать над сказанным мной, дискуссии не будет.
Я не понимаю, зачем ты написал:
>>Нафига нам BASM, об который спотыкается оптимизатор?
>А в чем был бы его смысл, если бы оптимизатор там не спотыкался?
Если бы оптимизатор не спотыкался на ассемблерных вставках, то в них было бы больше смысла. Заметь, я не имею ввиду, что оптимизатор должен что-то оптимизировать внутри этих вставок. Если ты до сих пор не понимаешь, о чём речь, то не следовало тебе вообще заикаться о BASM.
-
> BASM
Должен быть выход на более нижний уровень. Иначе получается JavaScript. И тут уж так - либо внешний ассемблер (+объектные файлы в нормальном формате (а не dcu), инфа для проверки типов, юниты-хЕдеры для импорта, дополнительные механизмы для сборки посредством makefile'ов etc), либо ассемблерные вставки.
-
> sdubaruhnul (07.09.07 12:11) [17]
> Мы говорим о языке Delphi или о BASM?
А какая нафих разница ?)
Мы с твоей подачи говорим о "тупом" дельфийском компиляторе, способном в т.ч. компилировать BASM-код и неспособном при этом предугадать ошибочные действия программера)
-
> есть такой язык - C - где проверки границ нет
Чушь пузатая) Где в языке Делфи какая-то там "проверка границ" ?
Только не надо трындеть про Range Checking - это фича конкретного компилятора, а не языка.
-
> Только не надо трындеть про Range Checking - это фича конкретного > компилятора, а не языка.
А какой смысл писать программы для сферических коней в вакуме? Они для компиляотора пишутся.
ЗЫ. Знаю, что программы пишутся для людей, заранее байан.
-
>Сергей М.
>Только не надо трындеть про Range Checking - это фича конкретного компилятора, а не языка.
Мы с твоей подачи говорим о "тупом" дельфийском компиляторе
Привет!
-
> sdubaruhnul (09.09.07 17:19) [26]
> Привет!
Привет-привет)
А вот и цитатка из справки:
Fundamental syntactic elements, called tokens, combine to form expressions, declarations, and statements. A > statement describes an algorithmic action that can be executed > within a program
. An expression is a syntactic unit that occurs within a statement and denotes a value. A declaration defines an identifier (such as the name of a function or variable) that can be used in expressions and statements, and, where appropriate, allocates memory for the identifier.
Директивы компилятора не попадают под подчеркнутое в цитате условие.
Равно как, например, текстовые директивы #pragma, #include в некоей С-шной программе или .IRP[C], .CODE, .ORG, .386 в некоей ASM-программе не относятся к к языку программирования, а являются лишь некими сообщениями конкретному компилятору.
-
>Сергей М. © (10.09.07 09:11) [27]
Да я не спорю, хотя в случае с Delphi всё прозаичнее: компилятор Delphi не от Borland в студию!?
Хорошо, другой пример, на сей раз касающийся языка и тоже положительный. Речь о директиве языка message. Очень правильно в Borland подумали о том, что нужно предоставить программисту удобное средство обработки сообщений и сделано это было на уровне языка (т.е. проблемы как таковой с языком почудить нет). Это при том, что сообщения в общем то часть операционной системы, а не языка или даже компилятора.
-
Вот ведь флудер.
RTFM
Remarks Applications should not call any system-defined functions from inside a callback function, except for PostMessage, timeGetSystemTime, timeGetTime, timeSetEvent, timeKillEvent, midiOutShortMsg, midiOutLongMsg, and OutputDebugString.
Можешь продолжать митинговать.
-
> DiamondShark © (18.09.07 13:30) [29]
Это мой огород для твоего камня ?)
-
>DiamondShark © (18.09.07 13:30) [29]
Чего пытаешься то? Остановить флудера одной меткой цитатой? Выделываетесь, батенька. Кстати, тему надо было всё-таки почитать, потому что ты так и не понял мою мысль. А она была простой. Где-то там в далёкой документации пишут:
"Applications should not call any system-defined functions from inside a callback function..."
Улавливаешь разницу? Не следует, но допустимо. По поводу слова "допустимо" см. [2].
-
> Это мой огород для твоего камня ?)
Чего ты такой подозрительный?
Это реакция на флуд и оффтоп товарища sdubaruhnul в сочетании с ответом на вопрос.
-
> [31] sdubaruhnul (18.09.07 18:04)
Ты случайно не ДелфиМастер - гопник ? %)
-
-
-
-
-
-
|