Неверное значение аргумента ТекстовыйДокумент.Записать(Ч, КодировкаТекста.ANSI)
В среде Турбоконф выполняю скрипт обращающийся к системному перечислению КодировкаТекста. Довольно часто (бывает по 20 раз в день) после каких то действий его значения портятся и стабильно возникает ошибка при их использовании. https://turboconf.ru/Tasks/9510
Воспроизведение ошибки
- Неизвестные действия
- Выполнить код
ТД = Новый ТекстовыйДокумент;
ИмяФайла = ПолучитьИмяВременногоФайла();
ТД.Записать(ИмяФайла, КодировкаТекста.ANSI);
Возникает ошибка Неверное значение аргумента ТекстовыйДокумент.Записать(ИмяФайла, КодировкаТекста.ANSI)
Ожидаемое поведение Ошибки не возникает
Окружение
- Версия: ОСкрипт 1.9
Ранее @bolsun обсуждал это с @EvilBeaver https://t.me/oscript_library/115250 Ошибка пропадает, если заменить перечисление на строку "utf-8". При замене на "ansi" пишет "Неверное имя кодировки".
Вот еще информация, которая может быть полезна: Не срабатывает условие в строке
if (rawValue == textEncodingEnum.Ansi)



Коллеги, без вашей помощи не обойтись. Нужно отловить момент выброса исключения и получить хотя бы стектрейс.
Коллеги, без вашей помощи не обойтись. Нужно отловить момент выброса исключения и получить хотя бы стектрейс.
ScriptEngine.HostedScript.Library.TextEncodingEnum.GetEncoding(IValue encoding, Boolean addBOM) в ScriptEngine.HostedScript.Library.TextDocumentContext.GetDefaultWriter(String path, IValue encoding) в ScriptEngine.HostedScript.Library.TextDocumentContext.Write(String path, IValue encoding, String lineSeparator) в lambda_method(Closure , TextDocumentContext , IValue[] ) в ScriptEngine.Machine.Contexts.AutoContext`1.CallAsProcedure(Int32 methodNumber, IValue[] arguments) в ScriptEngine.Machine.MachineInstance.ResolveMethodProc(Int32 arg) в ScriptEngine.Machine.MachineInstance.MainCommandLoop() в ScriptEngine.Machine.MachineInstance.ExecuteCode() в ScriptEngine.Machine.MachineInstance.ExecuteMethod(IRunnable sdo, Int32 methodIndex, IValue[] arguments) в ScriptEngine.Machine.Contexts.ScriptDrivenObject.CallAsFunction(Int32 methodNumber, IValue[] arguments, IValue& retValue) в TurboConf.HostApplication.HostApplicationForm.ExecuteScript(Script script, Keys ctrl, Keys alt, Keys shift, ScreenForm statusForm, String entryPoint, ScriptOptions options, IVariable[] parameters)
Воспроизвести вне TurboConf не получается.
@bolsun: после того, как начнет появляться ошибка, в выделенной на первом скриншоте строке чему равно textEncodingEnum.Ansi?
Появлется ли ошибка при использовании КодировкаТекста.OEM или КодировкаТекста.UTF8?
Строка "ANSI" - недопустимое название кодировки, используйте "windows-1251".
Как назло, сейчас перестало воспроизводиться.
КодировкаТекста.UTF8
Насколько я помню с этим значением так же возникала ошибка.
Воспроизвел
Пытаюсь понять когда точно возникает ошибка.
Думал, что достаточно было чтобы ИР Адаптер инициализировал COM соединение, но нужно именно чтобы еще подсказка адаптера сработала.
На вид - одинаково. Но если при этом действительно не срабатывает if (rawValue == textEncodingEnum.Ansi), значит, это разные объекты. Получается, в какой-то момент среда повторно инициализируется, и GlobalsManager создаёт копию перечисления. Как? когда? как поймать?
Замена == на Equals не поможет - метод перегружен.
На вид - одинаково. Но если при этом действительно не срабатывает
if (rawValue == textEncodingEnum.Ansi), значит, это разные объекты. Получается, в какой-то момент среда повторно инициализируется, иGlobalsManagerсоздаёт копию перечисления. Как? когда? как поймать?
в каком месте поставить точку останова, чтобы поймать момент повторной инициализации?
~и еще важный момент, скрипт вызывается асинхронно через Task, возможно в этот момент выполняется другой скрипт.~
и еще важный момент, скрипт вызывается асинхронно через Task, возможно в этот момент выполняется другой скрипт.
нет, не асинхронно, перепутал. Никакой другой скрипт в это время не выполняется.
Также считаю в данном случае, более надежно сравнивать значения по уникальному строковому идентификатору. Тогда бы такая ошибка не возникала.
в каком месте поставить точку останова, чтобы поймать момент повторной инициализации?
ContextDiscoverer, там 2 метода по поиску перечислений. В обоих поставить бряк
ContextDiscoverer
Я каждый раз создаю новый движок, при асинхронном вызове скрипта. Вызываю var engine = new HostedScriptEngine(); Там видимо и происходит регистрация перечислений заново. Но тогда архитектура движка непонятна,. Если он использует общие статичные перечисления в разных инстансах движка, то тогда точно сравнивать нужно по ключу.
в каком месте поставить точку останова, чтобы поймать момент повторной инициализации?
В TextEncodingEnum CreateInstance()
более надежно сравнивать значения по уникальному строковому идентификатору
Перечисления следовало бы сравнивать по числовому значению enum.
А сейчас в движке есть два существенно разных способа определить перечисления
ContextDiscoverer
Я каждый раз создаю новый движок, при асинхронном вызове скрипта. Вызываю var engine = new HostedScriptEngine(); Там видимо и происходит регистрация перечислений заново. Но тогда архитектура движка непонятна,. Если он использует общие статичные перечисления в разных инстансах движка, то тогда точно сравнивать нужно по ключу.
В таком сценарии надо смотреть не только на перечисления (они не статичны), а вообще на любые объекты, используемые с врапом. Могу предположить, что в какой-то момент у вас переменная-аргумент с кодировкой оказывается в одном AppDomain, а обернутое для сравнения значение в кишках движка в другом AppDomain.
Вот тестовый проект для воспроизведения https://disk.yandex.ru/d/nQrSRffrbJbnPw
Нажимать кнопку и сразу или через несколько нажатий возникнет эта ошибка.
Ошибка воспроизводится. Проблема в многопоточности.
Достаточно единственного вызова await Task.Run(() => RunScript(true));, и последующие RunScript(false); приводят к падению.
Я так понял проблему не стали решать. С ростом объема фонового кода я стал сталкиваться с ней все чаще в Турбоконфе. Прошу вернуться к ее рассмотрению. Вот свежий случай https://turboconf.ru/Tasks/10190
Я бы расчитывал на помощь @bolsun в этом вопросе, у меня нет сейчас возможности активно колупать систему типов в версии 1. Проблема вроде как разобрана, причина найдена, думаю починить сравнение перечислений можно относительно легко