Pull to refresh
17
0
Send message

Как я понял, startup time измеряется так:

# Ждем, пока главное окно приложения не станет отзывчивым

while (-not $process.MainWindowHandle)...

Мне кажется, тут довольно скользкий момент. Не понятно, в каком фреймворке как это устроено. В одних оно может стать отзывчивым до момента инициализации и отрисовки, в других - после. Я бы просто добавил вызов Close() в конце конструктора формы, после всех инициализаций, чтобы приложение запускалось, инициализировалось и сразу закрывалось. И измерил бы общее время работы процесса. Просто как вариант...

И жаль, что нет сборки WinForms под .NET Framework 4.x. Они совсем ведь разные фреймворки с .NET

helloworld приложение:

  • Delphi 7: ~380 KB, только windows

  • WinForms .NET Framework 4.0: ~9 KB, windows, а так же linux/MacOS через mono

Вышла версия BitImageTool v0.2, исправлены некоторые проблемы отображения интерфейса под Linux

Как я понял, отличить, системная она или созданная, можно только окольными путями, типа каких-то специфических полей через рефлексию. Поэтому, моё мнение - либо закрыть возможность создавать кисти/перья в свойствах, либо сделать метод расширения типа TryDispose

public static class Utils
{
    public static void TryDispose(this IDisposable obj)
    {
        try
        {
            obj?.Dispose();
        }
        catch { }
    }
}

чтобы потом вызывать как

public Pen pen1 { get; set; } = new Pen(color); // user defined pen
public Pen pen2 { get; set; } = Pens.White; // system pen
...
pen1?.TryDispose();
pen2?.TryDispose();

хотя, всё равно, пытаться вызывать Dispose для системных объектов, даже обёрнутых таким способом - не понятно, чем это обернётся. Мне больше нравится вариант - создавать их только на время отрисовки и не хранить в свойствах

Да, так и есть! На mono в линуксе вылетает исключение. Попробовал Dispose для кистей (которые по умолчанию в свойствах системные) в деструкторе одного контрола для BitImageTool и при закрытии приложения получил в консоли:

Unhandled Exception:
System.ArgumentException: This Pen object can't be modified.
at System.Drawing.Pen.Dispose (System.Boolean disposing) [0x0001b] in <...>:0
at System.Drawing.Pen.Dispose () [0x00000] in <...>:0
at (wrapper remoting-invoke-with-check) System.Drawing.Pen.Dispose()
at BitImageTool.BitEditor.Finalize () [0x00030] in <...>:0

Так что верно всё пишут, Dispose для системных ресурсов GDI+ вызывать нельзя. По крайней мере без заворачивания каждого в try-catch.

Так я тоже проверил, и у меня не вызывает. Ну а кто-то соберёт под другую версию фреймворка, или на моно каком-нибудь запустит и поймает исключение. Сколько лет топику - не важно. Сама идея вызова Dispose для системных ресурсов мне не кажется хорошей практикой, так что я просто убрал в обсуждаемом коде саму возможность использования системных кистей.

Просто вызываю Dispose. Для системных кистей проблем нет.

Вот тут пишут, что вызывать Dispose для системных кистей не следует, это может привести к исключениям. В крайнем случае, если нет гарантии, что кисти не системные, то каждый вызов Dispose придётся в отдельный try-catch заворачивать.

Хорошо, я переработал код примера контрола для winforms. Во избежание проблем убрал возможность задавать кисти, теперь используются кисти типа SolidBrush, задаются только цвета. Кисти и перья создаются только на время отрисовки с последующим вызовом Dispose().

Спасибо за замечание. В данном случае предполагается, что существование инстансов этого контрола завершается с закрытием приложения (кнопки на формах обычно создаются вместе с формами и существуют до конца работы программы). В этом случае система и так освободит unmanaged ресурсы процесса.

Если же, в каких-то целях, предполагается динамически создавать и уничтожать объекты данного типа в больших количествах на протяжении работы программы, то да, лучше добавить в код контрола деструктор с вызовыми Dispose() для всех объектов GDI+. Но тут тоже возникает проблема - если во время работы свойству или полю с типом Brush будет назначен не новый SolidBrush, а например системный объект типа Brushes.Red, то надо будет как-то определять этот момент, чтобы не вызывать Dispose() для системных кистей. В общем, тема спорная и не такая простая.

Как вы закрываете ресурсы объектов типа Pen, Brush в winforms? Поделитесь своим опытом.

Мой вопрос был в другом - если сделал не "как для самого себя", то есть функционально работает, но эстетически безобразно, то отказ вываливать "это" на публику - добросовестность или зажатость?

Ну, может автор гигабайтного "блокнота" просто не рефлексировал, и выложил как есть, кому надо - подберёт, не стал, так сказать, придерживаться ужасных парадигм :) Тут я, в общем-то, не осуждаю.

Но, самое настораживающее не в том, что кто-то выкладывает гигабайтные "блокноты", а в том, что другие, видя это, восклицают "а что, так можно было?" и гигабайтный софт с простой функциональностью постепенно становится нормой.

А как можно их отличить? Если добросовестность и есть форма зажатости, ограничения себя. По сути добросовестность - взятие на себя неких обязательств и выполнение их, в данном случае - перед потребителями твоего продукта, пусть и бесплатного.

Вот, к примеру, представьте, есть у человека одна полезная утилита, но сложная настолько, что он и сам порой забывает некоторые аспекты её работы, и приходится лезть в код разбираться. Будет ли добросовестным выкатить её релиз для общественности, в котором кроме него вряд ли кто-то что-то поймёт, а скорее, только время потеряет? В таком случае автор берет на себя обязательство не публиковать его до поры, пока не сделает удобным для неподготовленного пользователя. Что это - добросовестность? Зажатость? Самоедство? Или всё это и есть одно?

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

Интересный вариант, как я понял, там разрядность цвета для пикселей задаётся параметром.

Думал над четырехцветным вариантом своего метода (по 2 бита на пиксель = 3 цвета плюс фон), но там уже рисовать картинки в редакторе будет более трудоёмко, решил, что самое удобное и простое - один цвет, без палитр.

а не проще было расковырять панель машинки и попробовать припаять зуммер параллельно светодиоду? Или гарантия мешала?

Да, возможно, вы правы, спасибо за замечание. Этот код просто пример реализации, для наглядности метода, наверняка там ещё много можно оптимизировать.

Мне кажется, куда драматичнее ситуация, когда есть проекты функционально завершённые, и которыми сам регулярно пользуешься, но публиковать их в том виде, в каком они есть, как-то рука не поднимается. А долго вылизывать код и приводить к должному виду, чтобы не стыдно было выложить на всеобщее обозрение - не хватает какого-то бескорыстного трудолюбивого порыва.

так в этом нет смысла, другая скорость выбирается в настройках игры (например параметр sensitivity в q3), таким образом можно подобрать удобные настройки скорости и в системе и в игре даже без переключения dpi мышки. Тут главное - получить во время игрового процесса чистые данные с сенсора, не искажаемые системой, а там игровыми настройками уже докручивать и скорости и ускорения, при чём в некоторых играх даже индивидуально по каждой оси можно...

Красота - это конечно хорошо, но вот из-за такого интервального расположения групп цифр, больших букв и малых букв, пространство между ними набили разными значками (всякие скобки, больше, меньше и т.д.), которые могут являться управляющими символами в разных языках, например значки больше и меньше - края тегов в html.

А как бы красиво смотрелся алгоритм кодирования Base64 если бы набор цифр и букв обоих регистров в ASCII шёл последовательно, без лишних вкраплений. Буквально в одну строчку можно было бы кодировщик сделать, а не через таблицу или кучу ветвлений. И был бы он куда производительнее. Так что, всё зависит от позиции наблюдателя, или, как говорится, красота в глазах смотрящего.

2

Information

Rating
Does not participate
Registered
Activity

Specialization

Software Developer, Embedded Software Engineer
C#
AVR C
Development of printed circuit board
PCB design