Стартовая страница › Форумы › Разработка и интеграция › Потоки(Thread) — Программы(class) — Переменные
- В этой теме 123 ответа, 4 участника, последнее обновление 2 года назад сделано
manjey73.
-
АвторЗаписи
-
29.07.2024 в 08:55 #33646
manjey73УчастникЭто может быть полезно в некоторых случаях, например, вы можете создать метод, который принимает string имя типа в качестве параметра, получить тип с помощью Type.GetType метода и использовать Convert.ChangeType метод для изменения типа вашего объекта, а результат присвоить dynamic переменной. Таким образом вы можете выполнять любые операции с вашим динамическим объектом, но вам следует быть осторожным.Кстати, хотя это возможно, это не является предпочтительным способом.
Ну и
Вы не можете этого сделать, потому что C# это статически типизированный язык. Тип, который вы хотите привести, должен быть известен во время компиляции, чтобы компилятор мог использовать x как Control (или что угодно еще) в остальной части кода.Если бы вы могли сделать это:Собственно по ходу только reflection и ничего другого. Максимум это использование еще дополнительно Interface для метода, если он во всех классах программ будет всегда один, у меня он Run, хотя используя reflection в чистом виде я могу не только Run использовать, а что-то дополнительное, но мне вроде этого не нужно.
Convert.ChangeType — преобразует так же в объект, что мне ни холодно, ни жарко.
-
Ответ изменён 2 года, 1 месяц назад пользователем
manjey73.
29.07.2024 в 12:42 #33648
MikhailМодератор> Не совсем понял, чем мне поможет Calculator?
Калькулятор генерирует и компилирует код в процессе выполнения программы. Затем получает ссылки на методы и вызывает их. Может быть, это пригодится.Обычно программа сначала компилируется в dll или exe, а затем выполняется. Если нужно скомпилировать программу уже после её запуска, то это возможно, но несколько сложнее. Либо нужно использовать JavaScript, как сделано в драйвере MQTT. JavaScript не компилируется заранее, а транслируется при вызове скрипта.
Если я не заметил какой-то вопрос ко мне в большом объёме темы, напишите ещё раз.
29.07.2024 в 12:44 #33649
MikhailМодераторОпишите, в чём общая идея модуля? Как будет выглядеть работа с ним с точки зрения пользователя?
29.07.2024 в 12:54 #33650
manjey73УчастникМодуль должен позволять выполнять программы по принципу работы ПЛК.
То есть в dll Программ пишется код вида
public class Heater() { public bool EN; // входная переменная разрешающая работу программы public bool Q; // выходная переменная public uint EQ; // цифровой выход результата программы uint start = 0; // Стартовое значение программы (флаг) public bool terminated = false; public void Run() { while (!terminated) { // Тут чтение public переменных во внутренние - начало цикла if (EN) { start++; } EQ = start; // Здесь запись из внутренних в public - конец цикла Thread.Sleep(1000); } } }Где из фиксированных переменных будет только terminated и метод Run()
(это просто пример, программы могут быть совершенно разные, с разным количеством входных и выходных переменных, с разным типом входных и выходных переменных)Thread.Sleep — будет задаваться, это типа время цикла
public переменные будут связаны с каналами scada, ну а далее либо тут же управление, либо управление через МАУ, в зависимости от ситуации…По сути все программы это как бы виртуальные ПЛК.
29.07.2024 в 12:57 #33651
manjey73УчастникCalculator ведь не генерирует классы? он генерирует только функции (методы), если правильно понимаю.
Это разве позволит использовать множество переменных для виртуальной «программы»?
29.07.2024 в 15:43 #33652
JurasskParkУчастникНо ведь код можно компилировать и из самой библиотеки.
Не проще сделать обязательные интерфейс, которые в независимости от кода будут обязательные.
Просто вы пишете плагины для плагина.
То есть всё драйвера модуля уже являются плагином к скаде. А у вашего плагина свои плагины. Осталось только передать в ваш плагин входные данные пускай это будет список объектов, на выходе будет список значений в double, а внутри будет вызов и его остановка.29.07.2024 в 15:56 #33653
manjey73УчастникНет, это не плагин для плагина. Это отдельно сделанные классы выполнения программ, которые можно будет добавлять. А модуль должен их понимать и запускать в потоках.
Основная проблема — множество входных и выходных переменных.
Используя метод в него можно только передать много переменных как в Скриптах Scada.
Как извлекать переменные? кстати в Скриптах не пробовал делать через out или ref.
Но не это главное — как запускать одинаковые скрипты в разных потоках, выполняющие одинаковые задачи, но на разных установках ?С классами это без проблем, я сейчас так и сделал, просто надо допиливать.
Вот пример вывода в логе после остановки модуля — одна и та же программа запущена с разным выполнением цикла (использовал Thread.Sleep)Программа - di0 pi0 Heater Полное имя Scada.Server.Modules.ModXXX.Logic.Heater 0 - EN False 1 - Q False 2 - EQ 0 3 - cycle 0 4 - terminated False 0 - EN True 1 - Q False 2 - EQ 0 3 - cycle 1000 4 - terminated False Программа - di0 pi1 Heater Полное имя Scada.Server.Modules.ModXXX.Logic.Heater 0 - EN False 1 - Q False 2 - EQ 0 3 - cycle 0 4 - terminated False 0 - EN True 1 - Q False 2 - EQ 0 3 - cycle 3000 4 - terminated False Stop EQ = EQ 523 di0pi0 terminated = False di0pi0 terminated = True Stop EQ = EQ 175 di0pi1 terminated = False di0pi1 terminated = True 2024-07-29 15:51:24 Модуль ModXXX остановленИмя Класса программы взят из конфига — Heater
public class Heater() { public bool EN; // входная переменная разрешающая работу программы public bool Q; // выходная переменная public uint EQ; // цифровой выход результата программы public ushort cycle; // Задание цикла выполнения программы в мс public bool terminated = false; uint start = 0; // Стартовое значение программы (флаг) public void Run() { while (!terminated) { if (EN) { start++; } EQ = start; Thread.Sleep(cycle); } } }вот класс программы для тестирования.
з.ы. собственно задача почти решена, вылизывать код теперь и оформить во внешнюю dll код программ, сделать подключение dll в модуле и прописать using и все.Ну, не FBD конечно, но с пивом сойдет 🙂
29.07.2024 в 15:59 #33654
manjey73УчастникНасколько помню, чтобы один и тот же скрипт scada запускать в разных каналах, надо сильно поизвращаться (ранее с массивами) со словарями, чтобы скрипт запоминал промежуточные значения работы. Таймеры например, и так далее.
Здесь мы пишем программу как хотим, используем промежуточные переменные как нам нравится.
Надо еще будет решить задачу, по сохранению промежуточных переменных если нам нужно энергонезависимость, но это решается через файлы для программ, которые будут сохраняться каждую минуту (или сколько настроим)29.07.2024 в 18:23 #33655
JurasskParkУчастникНу, не FBD конечно, но с пивом сойдет ?
Да помню я, помню. Просто весь месяц в разъездах.
И вообще я его уже пятый раз переделываю.)29.07.2024 в 18:56 #33656
manjey73Участник@jurasskpark да это камень не в ваш огород, просто понимаю, что моей тямы на такое не хватит 🙂
Я вообще не думал про программы и потоки а начале, задача была передавать уставки в ПЛК или какое-то устройство управления по условиям или при задании из scada. Типа вставок температуры. Но из модуля. Есть там нюансы, которые на скриптах не реализовать в принципе, ну или можно упариться, так как надо разные условия проверять.
А потом как-то само в голову пришло, а почему бы и не Да?29.07.2024 в 18:59 #33657
manjey73УчастникНу и вот ковыряя модуль идея с FBD или ST родилась какая.
Чтобы это было расширением Scada некоторым, в котором создаёшь программу.
А модуль, чтобы их запускать соответственно.
Но вопрос такой, а можно ли сделать так, чтобы запуск этих же программ можно было вызвать из другого модуля и при этом управлять этой програмрой?
Вот загадка.29.07.2024 в 19:01 #33658
manjey73УчастникИли даже так. Запуском заведует не модуль, а само расришение.
То есть уйти вообще от такой вещи, как OnIteration модуля. Как бы параллельный сервер программ.30.07.2024 в 13:08 #33686
MikhailМодераторКомпоненты для мнемосхем — это тоже плагин для плагина и ничего страшного.
Вам нужно решить, кто будет компилировать класс:
1. Пользователь. И затем подкладывать dll
2. Ваш модуль.Будет полезно сделать общий базовый абстрактный класс (или интерфейс), от которого будут наследоваться создаваемые «программы». Тогда из кода модуля можно будет привести их к базовому типу и вызывать общие свойства и методы.
30.07.2024 в 13:09 #33687
MikhailМодераторНо не это главное — как запускать одинаковые скрипты в разных потоках, выполняющие одинаковые задачи, но на разных установках ?
Создавать отдельный экземпляр вашего класса и запускать его со своими аргументами.
30.07.2024 в 13:11 #33688
MikhailМодераторCalculator ведь не генерирует классы? он генерирует только функции (методы), если правильно понимаю.
Это разве позволит использовать множество переменных для виртуальной «программы»?
Генерирует целое множество классов. Если есть ссылка на объект (экземпляр класса), то можно к нему обращаться. Удобнее это делать через базовый класс или интерфейс.
-
Ответ изменён 2 года, 1 месяц назад пользователем
-
АвторЗаписи
- Для ответа в этой теме необходимо авторизоваться.