Цитата:
Сообщение от
gl00mie
и отключение Windows Ghosting не решает проблему взаимодействия с COM-объектами полностью, а вот перерисовку лечит!
Во-первых, спасибо gl00mie - способ действенный и давно многими используемый.
Но. Он отрубает современные механизмы управления приложением со стороны менеджера приложений виндов.
Пользователи видят, что окно не закрывается и не минимизируется, не перемещается мышкой - оно не живое. И так далее.
Давно хотелось найти более изящный способ.
Предлагаю попробовать такой способ решения для 2009:
- убрать WinAPI::disableProcessWindowsGhosting();
- добавить вызов infolog.yield(); почти в конец метода SysOperationProgressBase.update()
- в обработках и длительных операциях на клиенте, которые НЕ используют фреймворк SysOperationProgress расставить infolog.yield();
Суть проблемы:
- в виндах весь пользовательский интерфейс работает с сообщениями
- (почти) у каждого окна есть своя очередь сообщений
- по историческим причинам длина очереди ограничена размером 10000 сообщений (когда-то это казалось огромным числом)
- если главный поток приложения не разгребает очередь, то в современных виндах очередь очень быстро (за 3-5 секунд) заполняется и переполняется
- окна с переполненной очередью сообщений, винда помечает признаком "Не отвечает" и включает "магию" для зависших приложений. Магия была разной в разных версиях виндов. С современных виндах старая магия скорее мешает пользователям нежели помогает, а вот современная магия вроде ничё так.
метод disableProcessWindowsGhosting отрубает всю магию по работе с неотвечающим приложением. кроме того, этот метод не решает главную проблему - очередь сообщений остается переполненной. со всеми вытекающими последствиями от пропущенных виндовых сообщений.
современные практики программирования предполагают, что у каждого приложения есть основной поток, в котором крутится только пользовательский интерфейс, а вся реальная работа должна выполняться в отдельных потоках. но эта рекомендация не для старых приложений, которые были созданы в допотопные однопроцессорные времена.
в чем состоит мое предложение:
0. в длинные обработки в аксапте принято вставлять инфолог для пользователя.
1. в штатном режиме инфолог обновляет свое окошко не чаще 1 раза в секунду
2. давайте добавим вызов метода, который при обновлении окна позволит приложению обработать очередь системных виндовых сообщений. Насколько я понимаю происходящее в аксапте - это метод infolog.yield()
3. если ваша обработка не использует стандартный фреймворк, то расставьте infolog.yield() в своем коде так, чтобы он срабатывал не реже чем раз с 3-5 секунд.
=====================
пожалуйста, протестируйте на ваших системах.
на windows 10 работает неплохо.
также, если не сложно, обратите внимание ощущаете ли вы замедления/тормоза в работе приложения из-за добавленного infolog.yield?
=====================
добавлено 02.08.2020
в целом работает неплохо.
есть один звоночек о побочном эффекте (сам не видел):
если добавить infolog.yield в метод update,
то пользователь может получить доступ к интерфейсу аксапты пока работает код.
главное, что пользователь может сменить текущую компанию пока работает код обработки.
скорее всего, стоит добавить "стража" в окно где пользователь может менять компанию.