Турбоконф иногда блокирует ввод в точке останова

tormozit Закрыто Высокий

Плавающая проблема. Случается примерно раз в день уже давно. Писал об этом ранее тут https://turboconf.ru/Tasks/10444 (12)
[11.09.25 12:04:22:399] Warning: TurboConf: Подождите, идет процесс... Клавиатура и мышь временно заблокированы.
Проблема серьезная для пользователей, т.к. они врядли с первого раза поймут почему это происходит и как ее устранять.
[20250911 11-37-Ссылка скрыта

Комментарии

bolsun
#1, 11 сентября 2025 12:11

Что значит зависает? Как это проявляется, есть ролик?


tormozit
#2, ред. 11 сентября 2025 13:44

В этом состоянии Турбоконф выводит уведомления "Подождите, идет процесс... Клавиатура и мышь временно заблокированы.", но вызов скрипта при этом не выполняется насколько я могу судить (пытался проверять эту гипотезу много раз). Лечится так же (через окно "Выражение" или продолжение отладки) . Похоже на ту проблему. Потому я в контексте нее вчера и описывал эту проблему.


bolsun
#3, 11 сентября 2025 12:13

Зачем тогда вторая заявка, в чем ключевое отличие от нее?


tormozit
#4, 11 сентября 2025 12:16

(3) bolsun, обновил ответ (2)


bolsun
#5, 11 сентября 2025 12:22

В какой момент зависло, что в это время делал?


bolsun
#6, ред. 11 сентября 2025 12:23

Также прошу если прикладывается лог из директории, дополнительно прикладывать лог из конфигуратора (в нем есть важная дополнительная информация) и желательно хотя бы скриншот (сложно понять где искать проблему)


tormozit
#7, ред. 11 сентября 2025 12:25

Открыл окно "Выражение" командой скрипта "ВычислитьВыражение" (SHIFT+F9).


tormozit
#8, 11 сентября 2025 12:26

Техническая информация
Ссылка скрыта


bolsun
#9, ред. 11 сентября 2025 13:11

Хочу еще раз определить термин "зависает". Он же выводит сообщения о блокировке ввода?
В этот момент доступно меню по клику на иконке в панели задач?


tormozit
#10, 11 сентября 2025 13:42

(9) bolsun, Да, термин неподходящий. Заменил на "блокирует ввод". Про уведомление уже несколько раз писал - оно выводится. Похоже как будто Турбоконф вызывает скрипт, который чего то ждет. Но в логе при этом не видно незавершенного вызова скрипта.


tormozit
#11, 11 сентября 2025 13:46

(9) bolsun, Меню в трее на панели задач открывается, но, насколько я помню, клик не принимает


tormozit
#12, 11 сентября 2025 13:56

(11) tormozit, Да, сейчас снова словил это состояние. Меню в трее не принимает клик


tormozit
#13, 11 сентября 2025 13:58

Новый лог
Ссылка скрыта


tormozit
#14, 11 сентября 2025 13:59

В заголовке конфигуратора не видно добавки от Турбоконфа, но видны кнопки Турбоконфа.


bolsun
#15, 11 сентября 2025 14:28

В логе вижу, что был клик в главном меню конфигуратора, что вызывал?


tormozit
#16, ред. 11 сентября 2025 14:30

(15) bolsun, в какой момент времени?


bolsun
#17, 11 сентября 2025 14:31

(16) tormozit, вижу, что проблеме предшествовала ошибка

Warning: Не удалось выполнить скрипт ИРАдаптер->НажатиеEscape: ScriptEngine.Machine.ExternalSystemException: {Модуль C:\Portable\TurboConf\user_scripts\RDT.os / Ошибка в строке: 7445 / Внешнее исключение (System.Runtime.InteropServices.COMException): Не удается выполнить исходящий вызов, так как приложение обрабатывает входящий синхронный вызов. }
Значение = Locator.ConnectServer(".", "root\cimv2");


bolsun
#18, 11 сентября 2025 14:33

после этого сразу же была попытка установить текст и затем ТК уже перестал обновлять заголовок конфигуратора


tormozit
#19, ред. 11 сентября 2025 14:36

(17) bolsun, Проблема возникла в 13:54:32, а обозначенная тобой ошибка возникла в 13:55:03. Так что эта ошибка не может являться причиной проблемы

[11.09.25 13:54:32:751] Warning: TurboConf: Подождите, идет процесс... Клавиатура и мышь временно заблокированы.

[11.09.25 13:55:03:125] Error: Не удалось выполнить скрипт ИРАдаптер->НажатиеEscape
ScriptEngine.Machine.ExternalSystemException: {Модуль C:\Portable\TurboConf\user_scripts\RDT.os / Ошибка в строке: 7445 / Внешнее исключение (System.Runtime.InteropServices.COMException): Не удается выполнить исходящий вызов, так как приложение обрабатывает входящий синхронный вызов. }


bolsun
#20, 11 сентября 2025 14:44

Хронология

Проблема началась после перехвата нажатия Esc,
начался выполняться скрипт ИР
была установлена блокировка ввода
затем еще одно нажатие Esc через 500мс было уже заблокировано с уведомлением
Затем правый клик мышью через 300мс, тоже был заблокирован и т.д.
После этого ошибка выше и ТК уже дальше не обновлял заголовок.


bolsun
#21, 11 сентября 2025 14:46

После снятия блокировки, накопленные вызовы Esc снова привели к вызову ИР адаптера, и там уже возникла ошибка выше.


bolsun
#22, 11 сентября 2025 14:50

Это что касается причины возникновения уведомлений о блокировке.
К какому вызову относится ошибка первому или второму не ясно, т.к. после снятия блокировки скрипт еще выполнялся.


bolsun
#23, 11 сентября 2025 14:52

Кстати завершения первого вызова скрипта я не вижу в логе.
Вижу у второго [11.09.25 13:55:03:126] Замер: Время выполнения скрипта ИРАдаптер->НажатиеEscape: 9 ms//

А у первого так и не было сообщения о завершении выполнения. Т.е. он продолжал работать и видимо вызывать проблемы.


tormozit
#24, 11 сентября 2025 14:55

(23) bolsun, опять не сходится. Блокировка в 13:54:32. А первый вызов команды НажатиеEscape в 13:55:03

[11.09.25 13:54:32:751] Warning: TurboConf: Подождите, идет процесс... Клавиатура и мышь временно заблокированы.
[11.09.25 13:55:03:116] ExecuteScript user_scripts\RDT.os, entryPoint=НажатиеEscape, title=Обработка ирКлсПолеТекстаПрограммы: Модуль объекта - Конфигуратор - КомплекснаяАвтоматизация


tormozit
#25, ред. 11 сентября 2025 14:56

(23) bolsun, укажи точный момент времени где начался вызов обработчика скрипта и не завершился до 13:54:32


tormozit
#26, ред. 11 сентября 2025 14:58

Я вижу только один подходящий вызов - команды ВычислитьВыражение, о которой я писал в (7)
[11.09.25 13:54:29:725] ExecuteScript user_scripts\RDT.os, entryPoint=ВычислитьВыражение, title=[КА1 серверная] - Обработка ирКлсПолеТекстаПрограммы: Модуль объекта - Конфигуратор - КомплекснаяАвтоматизация


bolsun
#27, 11 сентября 2025 14:59

(26) tormozit, он кстати тоже не завершился.


bolsun
#28, ред. 11 сентября 2025 15:03

[11.09.25 13:54:29:725] ExecuteScript user_scripts\RDT.os, entryPoint=ВычислитьВыражение, - нет сообщения о завершении

[11.09.25 13:54:55:165] [ExecuteScript] ИРАдаптер - нет сообщения о завершении

[11.09.25 13:55:03:114] [ExecuteScript] ИРАдаптер - есть
[11.09.25 13:55:03:126] Замер: Время выполнения скрипта ИРАдаптер->НажатиеEscape: 9 ms


tormozit
#29, ред. 11 сентября 2025 15:33

(28) bolsun, Вот начало обработчика ВычислитьВыражение

//&ВосстанавливатьБуферОбмена
Процедура ВычислитьВыражение() 
	Сообщить("Команда.ВычислитьВыражение");

Т.е. он сразу должен писать в лог сообщение, которого мы в логе не видим. Значит проблема не в коде обработчика.


tormozit
#30, ред. 11 сентября 2025 15:43

Возможно проблема как то связана с обращением Турбоконфа к буферу обмена из-за аннотации &ВосстанавливатьБуферОбмена. А буфер обмена в этот момент допустим заблокирован окном конфигуратора.
[11.09.25 13:54:29:729] GetClipboard()


bolsun
#31, 11 сентября 2025 15:41

(30) tormozit, думал про это


tormozit
#32, ред. 11 сентября 2025 15:48

Попробуй тоже на асинхронное чтение буфера тут перейти. Если за секунду буфер не ответил то считать что он ответит никогда и идти дальше без его восстановления, но записать в лог инцидент. Но по факту буфер обмена у меня (интерактивно) в таких случаях всегда работал.


bolsun
#33, 11 сентября 2025 15:50

(31) tormozit, да скорее всего получение буфера вешает поток, т.к. в нормальной ситуации за этой строкой всегда должно идти docInfo=

[11.09.25 17:49:11:280] GetClipboard()
[11.09.25 17:49:11:280] docInfo=


bolsun
#34, 11 сентября 2025 16:02

(32) tormozit, у тебя есть готовый проверенный код для этого?


bolsun
#35, 11 сентября 2025 16:03

я написал свое решение, но вдруг какие-то побочки возникнут.


tormozit
#36, 11 сентября 2025 16:05

(34) bolsun, нет


bolsun
#37, 11 сентября 2025 17:08

Удалось воспроизвести похожие симптомы, если перед выполнением скрипта заблокировать буфер длительной операцией, например Ctrl+C на Общие модули.
Тогда интерфейс Турбоконф блокировал ввод, переставал обновлять заголовки окон и свой интерфейс, до тех пор пока буфер не освободится.


bolsun
#38, 11 сентября 2025 17:10

6.4.9385.34339


bolsun
#39, ред. 11 сентября 2025 17:14

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


bolsun
#40, 11 сентября 2025 17:12

Для всех остальных вызовов GetClipboard я добавил дополнительное логирование с отметкой начала получения буфера и окончания, в случае проблем можно будет отследить являлось ли это причиной.


tormozit
#41, ред. 11 сентября 2025 17:20

(39) bolsun, а восстановление буфера при завершении скрипта сделал асинхронным?


bolsun
#42, 11 сентября 2025 17:32

(41) tormozit, нет, этот метод вроде устойчив к блокировке буфера. Будем смотреть по мере возникновения проблем.


bolsun
#43, ред. 11 сентября 2025 17:41

А вообще почему такая блокировка может возникать, что блокирует буфер? У меня насколько я помню ни разу таких проблем не было, кроме специально вызванных.


bolsun
#44, 11 сентября 2025 18:09

6.4.9385.35867
https://disk.yandex.ru/d/XRPUNWQtrbwBUw

Добавил временные отметки также для методов установки буфера обмена.


tormozit
#45, ред. 11 сентября 2025 19:30

(42) bolsun, Да. Обычно такая проблема касается именно чтения из буфера объекта, который туда помещен не целиком, в виде "ссылки".
(43) bolsun, Вроде как проблема появляется, если в буфере обмена есть какой то из форматов 1C:MD8 https://partners.v8.1c.ru/forum/t/1937892/m/1939506 Раньше конфигураторы блокировали друг друга из-за этого. Но ту проблему вроде исправили, но скорее всего у нас что то похожее.


tormozit
#46, ред. 11 сентября 2025 19:35

Delayed Rendering - отложенная выдача содержимого буфера обмена https://learn.microsoft.com/en-us/windows/win32/dataxchg/clipboard-operations . Применяется для экономии памяти и времени на копировании большого объекта из памяти процесса в буфер обмена.
Как это работает:

  1. Программа помещает в буфер обмена не сами данные, а их описание (формат и возможность отложенной передачи)
  2. Когда другая программа запрашивает данные, система отправляет сообщение WM_RENDERFORMAT программе-источнику
  3. Программа-источник обрабатывает запрос и предоставляет актуальные данные


tormozit
#47, ред. 11 сентября 2025 19:37

(46) tormozit, Если в момент чтения такого формата из буферам программа-владелец такого объекта заморожена, то читатель буфера встает в ожидание.


bolsun
#48, 11 сентября 2025 20:33

Но что именно в связке ТК + ИР приводит к этому. На чистом ТК такой проблемы вроде бы никогда не было.
Я подозреваю либо фоновые методы, либо запоминание позиции через буфер, либо получение снимка объектов через буфер из дерева конфигурации.


bolsun
#49, ред. 11 сентября 2025 20:37

Но т.к. проблема возникает, я так понимаю, только в момент останова, может быть причина в кривой логике платформы при работе с буфером.


tormozit
#50, ред. 12 сентября 2025 13:03

Сейчас в точке останова вызвал команду "Перейти к определению" (CTRL+F12). Получил ошибку и зависание Турбоконфа без вывода уведомлений о блокировке ввода.
System.TimeoutException: Не удалось получить значение буфера обмена за заданное время 1000мс
в TurboConf.Core.Helpers.hvEDaEgD=9M6v<8lhw=,LC0F$.MoveNext()
Ссылка скрыта


bolsun
#51, ред. 12 сентября 2025 13:52

(50) tormozit, т.е. после вывода сообщения нормальная работа программы не возобновилась и ее пришлось завершать принудительно?


tormozit
#52, ред. 12 сентября 2025 14:04

(51) bolsun, работа Турбоконфа возобновилась после разморозки отладки (выхода из остановки отладки). А в заморозке отладки Турбоконф не реагировал на все команды ввода и не убирал уведомление и не показывал добавку в заголовке конфигуратора.


bolsun
#53, 12 сентября 2025 14:04

(52) tormozit, значит асинхронное выполнение не помогает.
Это весь лог?


tormozit
#54, 12 сентября 2025 14:06

(53) bolsun, вот продолжение
Ссылка скрыта


tormozit
#55, 12 сентября 2025 14:09

В логе есть
[12.09.25 12:57:08:092] Клик на уведомление, снимаем блокировку.
Но фактически она не снялась.


bolsun
#56, ред. 12 сентября 2025 14:10

(54) tormozit, можешь нормальный кусок лога прислать, с событиями до и после?


tormozit
#57, 12 сентября 2025 14:15

(56) bolsun, Ссылка скрыта


bolsun
#58, 12 сентября 2025 14:18

(57) tormozit, в логе не вижу завершения скрипта ПерейтиКОпределению, либо он обрезан. Если не хочешь присылать полный лог, ищи тогда в нем информацию по незакрытым GetClipboard, SetClipboard и незавершенным вызовам скриптов.


bolsun
#59, 12 сентября 2025 14:20

(55) tormozit, если блокировка не снялась, как ты продолжил отладку?


tormozit
#60, 12 сентября 2025 14:21

(59) bolsun, окно конфигуратора не блокировалось


tormozit
#61, 12 сентября 2025 14:22

(58) bolsun, Вот фрагмент от начала до конца вызова обработчика ПерейтиКОпределению скрипта
Ссылка скрыта


bolsun
#62, 12 сентября 2025 14:25

(61) tormozit, посмотри в полном логе, есть ли незакрытые GetClipboard, SetClipboard до начала вызова скрипта.

Например, GetClipboard() with id 638932786236449514 has started...
должен быть закрыт GetClipboard() with id 638932786236449514 has finished.


tormozit
#63, ред. 12 сентября 2025 14:32

(62) bolsun, Все закрыты. Что кажется логичным, т.к. по внешним признакам поток просто ждал какую то блокировку и через минуту я ее снял путем продолжения отладки. Кстати в предоставленном тут логе закрытие 638932786236449514 есть
[12.09.25 12:58:22:127] GetClipboard() with id 638932786236449514 has finished.


bolsun
#64, 12 сентября 2025 14:32

(60) tormozit, значит блокировка ввода снялась.

Теперь что-то проясняется.

Да, в логе вижу, что выполнение скрипта висело до тех пор пока не была продолжена отладка и сразу появилось сообщение
[12.09.25 12:58:22:127] GetClipboard() with id 638932786236449514 has finished.

Т.е. асинхронный вызов отработал, скорее всего заблокировал поток программы этот вызов в скрипте.

СтароеЗначениеБуфераОбмена = ТурбоКонф.ПолучитьБуферОбмена();


bolsun
#65, 12 сентября 2025 14:33

ТурбоКонф.ПолучитьБуферОбмена();

Этот метод не логируется, поэтому мы не увидели его вызова.


tormozit
#66, 12 сентября 2025 14:34

(64) bolsun, Да, вполне возможно.


bolsun
#67, 12 сентября 2025 14:35

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


bolsun
#68, 12 сентября 2025 18:15

6.4.9386.35327

API

  • Метод ПолучитьБуферОбмена теперь работает асинхронно, в случае если не удалось дождаться содержимого буфера обмена за заданный интервал, будет выброшено исключение.

ПолучитьБуферОбмена(ФорматДанных="", Таймаут=1000)

https://disk.yandex.ru/d/XRPUNWQtrbwBUw


tormozit
#69, ред. 12 сентября 2025 18:38

(68) bolsun, По-хорошему это конечно должно было быть сделано в NetFreamework, но видимо что то не учли. Может в ее более поздних версиях что то улучшили. На всякий случай покажи код, которым ты читаешь буфер. В КлипАнгеле я читаю через

iData = Clipboard.GetDataObject()
if (iData.GetDataPresent(formatName))
     iData.GetData(formatName)

Возможно и мне в КлипАнгеле стоит об этом задуматься. Но я не обращаюсь к отложенным (ссылочным) форматам типа "1C:MD8***".


bolsun
#70, ред. 12 сентября 2025 21:07

(69) tormozit,

        public static string GetDataFromClipboard(string format)
        {
            TurboApi.TraceDebug("GetDataFromClipboard()...");
            
            if (Clipboard.ContainsData(format))
            {
                var stream = Clipboard.GetData(format) as MemoryStream;

                if (stream == null)
                {
                    throw new Exception("Stream is Null: " + format);
                }

                var buffer = new byte[stream.Length];
                stream.Read(buffer, 0, (int)stream.Length);

                return Encoding.UTF8.GetString(buffer);
            }

            return "";
        }
        
        public static Task<string> GetDataFromClipboardAsync(string format)
        {
            var tcs = new TaskCompletionSource<string>();
            Thread staThread = new Thread(() =>
            {
                try
                {
                    string text = GetDataFromClipboard(format);
                    tcs.SetResult(text);
                }
                catch (Exception ex)
                {
                    tcs.SetException(ex);
                }
            });
            staThread.SetApartmentState(ApartmentState.STA);
            staThread.Start();
            return tcs.Task;
        }
        
        public static async Task<string> GetDataFromClipboardWithTimeoutAsync(string format, int timeout)
        {
            var sw = new Stopwatch();
            sw.Start();

            try
            {
                var clipboardTask = GetDataFromClipboardAsync(format); // your existing code
                var timeoutTask = Task.Delay(timeout);

                var completedTask = await Task.WhenAny(clipboardTask, timeoutTask);
                if (completedTask == clipboardTask)
                {
                    // Clipboard read completed in time
                    return clipboardTask.Result;
                }
                else
                {
                    // Timeout occurred, do not wait for the STA thread to finish
                    throw new TimeoutException("Не удалось получить значение буфера обмена за заданное время " + timeout + "мс");
                }
            }
            catch (Exception e)
            {
                TurboApi.TraceError(e.ToString());
                throw;
            }
            finally
            {
                sw.Stop();
                TurboApi.TraceMeasurement("Время получения буфера: " + sw.ElapsedMilliseconds + "ms");
            }
        }


tormozit
#71, 13 сентября 2025 00:42

Проблему в работе конфигуратора с буфером обмена отправил в тех.поддержку 1С https://www.hostedredmine.com/issues/1007167


tormozit
#72, ред. 13 сентября 2025 08:33

В C# зависает сразу на методе Clipboard.GetDataObject(). А это похоже означает, что внутри он сразу пытает получить данные всех форматов даже отложенных. Это выглядит нелогично, но других объяснений я пока не нахожу.

Сделал в КлипАнгеле 2.19 регулярное удаление из буфера не текстовых форматов, если владелец буфера - процесс 1С и он не отвечает.

Предлагаю в Турбоконфе сделать аналогичный анализ и при обнаружении такой ситуации получить через winAPI данные только текстовых форматов и установить уже эти данные в буфер через DataObject.


[DllImport("user32.dll")]
        private static extern bool IsHungAppWindow(IntPtr hWnd);

[DllImport("user32.dll")]
        private static extern bool IsClipboardFormatAvailable(uint format);

[DllImport("user32.dll")]
        private static extern uint RegisterClipboardFormat(string lpszFormat);

        public struct ClipFormat
        {
            public string Name;
            public uint Id;
            public ClipFormat(string name, uint id)
            {
                Name = name;
                Id = id;
            }
        }

        private void fix1CFormat()
        {
            //IDataObject iData = Clipboard.GetDataObject(); // Зависает
            ClipFormat[] formats = new ClipFormat[]
            {
                new ClipFormat("1C:MD8", 0),
                new ClipFormat("1C:MD8 Info", 0),
                new ClipFormat("1C:MD8 External Data", 0)
            };
            for (int i = 0; i < formats.Length; i++)
            {
                formats[i].Id = RegisterClipboardFormat(formats[i].Name);
            }
            bool formatFound = false;
            foreach (ClipFormat clipFormat in formats)
            {
                if (IsClipboardFormatAvailable(clipFormat.Id))
                {
                    formatFound = true;
                    break;
                }
            }
            if (formatFound)
            {
                ClipboardOwner clipboardOwner = GetClipboardOwnerLockerInfo(false);
                if (true
                    && clipboardOwner.application.StartsWith("1cv8")
                    && IsHungAppWindow(clipboardOwner.windowHandle))
                {
                    CopyClipToClipboard();
                }
            }
        }


tormozit
#73, ред. 13 сентября 2025 11:55

Сейчас снова вылезло уведомление о неудачном чтении буфера обмена при вызове команды скрипта "Вычислить выражение". Но теперь через секунду заморозки работа Турбоконфа продолжилась (нарисовались кнопки скрипта в окне "Выражение"). Однако при вызове подсказки Т9 опять получил уведомление о блокировке
[13.09.25 11:47:57:705] GetClipboard() with id 638933608777055341 has started...
[13.09.25 11:48:02:559] Warning: TurboConf: Подождите, идет процесс... Клавиатура и мышь временно заблокированы.
[13.09.25 11:49:06:489] GetClipboard() with id 638933608777055341 has finished.
Ссылка скрыта


bolsun
#74, ред. 13 сентября 2025 12:14

(73) tormozit, асинхронное получение буфера используется только при вызове скрипта (для восстановления буфера) или через API в скриптах. Весь встроенный функционал работает по прежнему синхронно.


bolsun
#75, 13 сентября 2025 12:16

У меня под сотню синхронных методов где вызывается GetClipboard, переделывать их все на асинхронные такое себе...


bolsun
#76, 13 сентября 2025 12:25

Можно конечно сделать вызов асинхронного внутри синхронного, но почему то это в каких то случаях приводит к зависанию.


bolsun
#77, ред. 13 сентября 2025 12:38

И опять же, почему так участились эти случаи, раньше же их не было совсем? Проблема участилась только в 8.3.27?
Я использую 8.3.23 у меня нет таких проблем.
Но я в процессе тестирования почти не использую команды ИР, а ТК не часто получает нетекстовые форматы 1с через буфер.


tormozit
#78, 13 сентября 2025 13:11

Можно попробовать сделать удаление отложенных форматов из буфера (72) при срабатывании таймаута чтения буфера.


bolsun
#79, 13 сентября 2025 13:49

(73) tormozit, странно, что такая проблема возникла при вызове подсказки, т.к. ТК не должен был получать буфер в этом случае. Проверю.


bolsun
#80, 13 сентября 2025 14:56

6.4.9387.30334

  • Убрано ненужное получение буфера обмена при вызове подсказки T9 в некоторых случаях.

https://disk.yandex.ru/d/XRPUNWQtrbwBUw


bolsun
#81, 13 сентября 2025 15:03

(72) tormozit, в примере не хватает имплементации этого кода.

                ClipboardOwner clipboardOwner = GetClipboardOwnerLockerInfo(false);
                if (true
                    && clipboardOwner.application.StartsWith("1cv8")
                    && IsHungAppWindow(clipboardOwner.windowHandle))
                {
                    CopyClipToClipboard();
                }


tormozit
#82, ред. 13 сентября 2025 15:46

(81) bolsun, https://github.com/tormozit/ClipAngel/blob/a676beac8a3a0ae090ef155e3213775cc2bbed09/Main.cs#L2196
CopyClipToClipboard() - специфичная для ClipAngel логика, т.к. у него уже заранее есть копия содержимого буфера. В случае Турбоконфа наверное нужно реализовать собственное чтение текстового формата из буфера через WinAPI, т.к.Clipboard.GetData(format) у нас блокируется даже для простого текстового формата как я понял. Хотя если через WinAPI получится считать текст из буфера без блокировки, то остальные меры выглядят избыточными. Если же через WinAPI прочитать текст без блокировки не получится, то можно просто очистить буфер в этой ситуации, т.к. это случается редко.


bolsun
#83, ред. 13 сентября 2025 17:01

(82) tormozit, получение текста буфера через WinApi вроде бы не вызывает блокировок при зависшем буфере.
Если это подтвердится тестированием, переход на такой метод, для меня решит 99 процентов проблем, т.к. в основном я использую только текст из буфера. Получение с форматом использую только в некоторых методах, в них можно использовать асинхронную реализацию с очисткой буфера (что вроде бы также на первый взгляд работает).

Дя, посмотрел, реализация метода Clipboard.GetText() в .NET неоптимальная, им не следовало использовать GetDataObject() в этом случае.


tormozit
#84, ред. 13 сентября 2025 17:04

(83) bolsun, тоже посмотрел на реализацию GetDataObject()
https://github.com/dotnet/winforms/blob/62ebdb4b0d5cc7e163b8dc9331dc196e576bf162/src/System.Windows.Forms/src/System/Windows/Forms/OLE/Clipboard.cs#L79
Мои опасения подтвердились - там сразу все данные извлекаются, т.е. можно считать все функции чтения буфера обмена в NetFramework работают довольно неэффективно с отложенными форматами, т.к. сначала зовут GetDataObject(). Например если в буфере лежит имя формы 1С "ФормаСписка" и ее отложенные данные 2МБ и нам надо взять только имя, то платформа Net будет извлекать эти 2МБ данные формы через отложенный формат с ощутимой задержкой и опасностью блокировки.


bolsun
#85, ред. 13 сентября 2025 17:16

(83) думаю проверять на зависшее приложение и перезаписывать буфер при превышении таймаута для метода GetDataObject() тогда нет смысла. Буду просто исключение выбрасывать.


tormozit
#86, 13 сентября 2025 17:20

(85) bolsun, В принципе да, так меньше риска внесения побочных эффектов.


bolsun
#87, 13 сентября 2025 17:24

6.4.9387.34804

  • Текст буфера теперь получается через нативные методы WinAPI, а не метод .NET Clipboard.GetText().

https://disk.yandex.ru/d/XRPUNWQtrbwBUw


bolsun
#88, 13 сентября 2025 17:31

(87) но не все методы еще заменил, во многих местах пока используется Clipboard.GetText().
В 66 местах используется новый метод, в 44 еще старый.
Оказывается ровно 100 вызовов в коде )


bolsun
#89, ред. 13 сентября 2025 17:32

(88) нет, 110 )


bolsun
#90, 13 сентября 2025 17:34

Проверь пока в скриптах как стало работать, в API новый метод.


tormozit
#91, ред. 13 сентября 2025 17:48

(90) bolsun, при длительной операции конфигуратора, владеющего буфером, и отключенном КлипАнгеле Турбоконф успешно выполнил вставку слова. Правда раньше я такого теста не проводил. И непонятно как теперь понять, что тест пройден успешно в той плавающей ситуации с точкой останова. Видимо только накоплением длительности бессбойной работы.


bolsun
#92, 13 сентября 2025 21:25

6.4.9387.42064
https://disk.yandex.ru/d/XRPUNWQtrbwBUw

Заменил все остальные вызовы получения буфера.


tormozit
#93, 17 сентября 2025 00:04

Больше не зависает и не блокирует ввод.
tormozit изменил статус на Закрыто


Для вставки изображения или файла, перетащите его в поле редактора или вставьте файл из буфера