Pull to refresh
-3
0
Иван Мокров @Lincoln6Echo

User

Send message
Если вы задаетесь и заморачиваетесь такими вопросами (правильными), то вы станете отличным .net-кодером, и MVP вас не минует.
Я отвечу попроще, иронично метафорично, не пинайте (подробнее и точнее лучше конечно MSDN читать). У нас, если грубо выражаться, есть два менеджера памяти — виндовый, и .net-нетовский CLR. И они между собой не совсем дружат. Каждый из них время от времени дефрагментирует свой кусок памяти, очищает мусор, перекидывает что-то в своп из физической памяти, но каждый как-бы сам по себе. Когда мы должны обменяться блоком памяти между управляемой и неуправляемой архитектурой, то стоит сделать Lock и GCHandleType.Pinned — это типа как прибить гвоздем к холодильнику записку «этот кусок памяти никому не трогать и не перемещать». Иначе, пока физической памяти много, 100 раз, даже 1000 раз всё будет ОК, а на 1001-й раз винда решит что-то свопнуть, про что не в курсе, и по нужному адресу вместо блока памяти нужного битмапа окажется кусок порнофильма, что я вчера скачал, и мне придется краснеть.
Убедили, сделано, сорцы обновил
Блин, кажется я комментарием выше сделал рекурсивную ловушку, и теперь эти камрады знают, что они чего-то не знают, что их может напугать.
Немного добавлю. У меня был этот вариант с lockobject и методами BeginPaint() и EndPaint() во фронтэнде, которые через Monitor лочили. Но, стало выглядеть сложнее, хотя и правильнее с точки зрения продакшн. Вот честно, я побоялся напугать заморочками в коде не очень опытных камрадов.
Плюсую! Потому-что сам с такой фигней уже воткнулся. Но, я не знаю что стоило выбрать приоритетом для статьи — железную надежность, или простоту восприятия и короткий код. Выбрал — простой короткий код. Тем, кто поопытнее, у них вопросов не возникнет, сами переделают библиотеку под себя, у них нет вопросов, и тестовые семплы WPF и WF им даже не нужны.
А тем, кто только начал кодить, им лучше попроще показать, и если что постепенно, до хардкора доберутся с потоками поиграются, с дебагером. Насколько смог, чтобы всем польза и позитив были.
В хорошем или плохом смысле?
Не ругайте за занудство с подробностями, но ЕМНИП, WIn32 API и GDI появились еще в Windows NT4.0. К чести Microsoft он так и не менялся (ради обратной совместимости), лишь добавлялись новые методы. А если старые «прокачивались» функционалом, то оставался старый как был, а к «прокаченому» варианту метода добавлялось окончание «Ex» (extended), напр. CreateWindowEx().
Хардкорные трюки ч.2 как раз будет этому посвящена, и там тоже будут печеньки для дотнетчиков.
.
P.S. Что касается выпиленых API в WP8 и WinRT. Камрады, не будьте такими наивными. Там все-еще старый добрый NT4, который компилился со своим Win32 API под кучу процов еще многие лета назад. Вспомнили, пересобрали на ARM и нахлобучили сверху WPF. «WinRT doesn't completely replace Win32 API but internally can call and use Win32 API and subsets of .Net.»
Вот только использовать Win32 теперь запрещено волевым усилием и политикой компании, и модерацию в магазине приложений не пройдете. Отчасти напоминает политику Apple по отношению к API. Огромная просьба, не реагировать и не начинать холивар на эту тему. Статья выше совсем о другом.
Уважаемый, в статье была все-таки отсылка на WriteableBitmap с его сферой применения. Но, давайте честно скажем, что и на андроиде мой подход тоже не будет работать. Ок, я принимаю эту критику.
Вероятно, вы просто далеки от задач, в которых нужно именно то, о чем в статье написано, и если вы с такими задачами не сталкивались, и не понимаете о чем речь, значит вам в какой-то степени повезло, и эта статья не для вас. Просто поставьте в закладки (на всякий будущий случай и сюрпризы жизни кодера) и не забивайте пока себе голову.
Мысли сходятся. Пока зачекинил исправления с Dispose в исходниках на CodePlex.
Да-да, дружище, увидел уже этот косяк, сейчас переношу BMP и GFX уровнем ниже в контрол, и прикручиваю реакцию на резайз. Жую мозг как бы это сделать не поломав статью.
Вы меня выкупили! ) Действительно, я тут отнесся к Dispose() как к некоему «Clear and Go again» (управляемых ресурсов в классе нет), и сэкономил несколько строк кода. Но, ОК, критику принял, буду допиливать. (Напишу в личку как появится апдейт)
IDisposable реализован вроде правильно — в классе нет управляемых ресурсов, и полный паттерн не нужен. Однако нужно наследование от интерфейса, иначе если кто-то начнет бесконечно лупить в цикле рендера
myRazorPainter = new RazorPainter();
то начинаются memory leaks несмотря на деструктор.
Если укажите в чем именно моя ошибка буду благодарен (и не только я).
Потому-что паттерн и сценарий использования не определен, и я сделал как проще (надеюсь) для понимания. Для моей задачи они будут совсем в другом классе в другой либе рисоваться.
ReleaseHdc() возможно и перекрутил на сырую голову, хотя у себя проблем не заметил…
Лет через будем 5 вместе с теплотой вспоминать 15K FPS, смастырив на новых проце, шине и памяти контрол на 1M FPS )
Голосуешь за готовый WinForms контрол на CodePlex? Не знаю есть ли смысл, фронтэнд для такого контрола прост, его смастырить несложно.
Но, пожалуй, завтра таки добавлю WF вариант контрола, хотя он на порядок проще WPF-варианта, но многим пригодится как стартовая точка.
Ссылка на CodePlex открыта, исходники есть, ссылка на репозитарий сорцов есть, можно подключиться к проекту и «прокачать» его до С++\CLI. Я на хабре этот пост закоммитил не ради «я пиарюсь», а просто показать неожиданный для многих подход к сложным вещам. И напомнить, что Win32 API еще живее всех живых, и чертовски умопомрачительно эффективен.
Я думал об этом, но в итоге, все-равно каждый кадр, который надо нарисовать на мониторе стал бы методом или unsafe C++ .Net, или вызовом неуправляемого Win32 API неважно откуда.
Я понимаю, что обидел тех, кто из управляемого С++ вызывает GDI32. Парни, я спецом убивался о простоте и изяществе, чтобы портировать решение в 100 строк кода не было проблемой. 15 минут труда и будет у вас управляемый С++ контрол, работающий даже быстрее моего решения в посте для C#.
Да я тоже неделю убил на разные варианты, пока до самого «дна» GDI32 не опустился)
Думал умные люди из Microsoft за эти годы уже давно всё придумали, но, оказалось, они додумались только до контрола D3DImage у которого хостится контрол с DC, к которому можно привязать DirectX. Честно говоря, я еще думал про старый добрый DirectDraw, с ним я тоже много 2D фокусов проделывал, но его ЕМНИП прекратили еще в DirectX8, да и фротэнд контрола получился бы все-равно не таким красивым.
Конечно сразу додумался, однако при крайнем, экстремальном тестировании производительности, когда дело касается графики, то критерий — FPS. Но была причина еще важнее — контроль утечек памяти, что особенно актуально для работы с Win32 и маршаллингом из управляемого кода. Чем больше и чаще рисуем тем быстрее увидим проблему. У меня ночь проработала на 15000 и все ОК, только после этого решился публиковать.
12 ...
28

Information

Rating
Does not participate
Location
Люберцы, Москва и Московская обл., Россия
Registered
Activity