VB.NET Синхронизация путаница - PullRequest
0 голосов
/ 13 января 2011

VB.NET, .NET 4

Привет всем,

У меня есть приложение, которое управляет промышленной системой. Он имеет графический интерфейс, который после запуска процесса в основном отображает состояния различных подключенных устройств. В основном это работает так:

  • Объект System.Timers.Timer всегда работает. При каждом событии Elapsed он опрашивает устройства на предмет их текущих значений и вызывает элементы управления в графическом интерфейсе, обновляя их новыми значениями.
  • Нажата кнопка запуска, создан и запущен объект секундомера времени процесса (теперь в GUI System.Timers.Timer's вызываются и обновляются метки в дополнение к другим работам, которые выполняются в это событие)
  • Создан новый поток, который выполняет подпрограмму Process ()
  • Некоторые объекты секундомера создаются и запускаются (эти секундомеры периодически перезапускаются во время процесса с помощью метода Restart ().
  • Некоторая логика выполняется в свойствах Elapsedmilliseconds новых секундомеров, чтобы определить, когда нужно делать такие вещи, как запись новых заданных значений на устройства, обновление журнала данных и т. Д. *

Вот моя проблема: программа иногда зависает. Мои неосведомленные усилия по выявлению проблемы привели меня к подозрению, что чтение / запись на подмножество устройств, управляемых через RS-232, большую часть времени являются виновниками. Тем не менее, я иногда вижу другие странные вещи при зависании программы, например, одна из меток времени, свойство Text которых определяется свойством Elapsedmilliseconds секундомера, иногда будет показывать невозможное значение (например, -50 часов или около того).

Что касается проблем RS-232, я подозреваю, что что-то вроде события чтения выполняется одновременно с событием записи, и это вызывает остановку (?). Я попытался предотвратить это, убедившись, что вся связь с устройством RS-232 направлена ​​через подпрограмму Transmit (), которая имеет следующий атрибут:

Что, насколько мое невежество позволяет мне понять, должно заставить одно выполнение Transmit () завершиться полностью, прежде чем может начаться другое. Возможно, существует еще один риск, что код будет заблокирован здесь, если один Transmit () никогда не завершится?

Что касается проблемы с секундомером, я предполагаю, что проблема заключается в том, что таймер пытается обновить метку графического интерфейса в то же время, когда выполняется метод Restart () секундомера. Я не уверен, может ли это вызвать проблемы. Все, что я знаю, это то, что эта проблема возникла только в тот момент процесса, когда будет сделан вызов Restart ().

Мне интересно, смогу ли я использовать SyncLock или что-то еще для блокировки секундомера во время обновления метки (или, наоборот, при перезапуске)? Или, может быть, я должен остановить таймер, перезапустить секундомер, а затем снова запустить таймер, вот так?:

Timer.Stop
Stopwatch.Restart
Timer.Start

Мое трепетное отношение к дальнейшим действиям связано с моим полным отсутствием понимания того, как на самом деле работают объекты синхронизации .NET. Я попытался наложить несколько SyncLocks в разных местах, но я действительно понятия не имею, правильно ли они реализованы или нет. Мне интересно, если, предоставив весь этот контекст, кто-то действительно умный сможет рассказать мне, как я глуп и как это сделать правильно. Я был бы очень признателен за любой вклад. Если бы было полезно предоставить некоторые фрагменты кода, я был бы рад, я просто волнуюсь, что все настолько запутано, что это просто отвлекает от того, что, я надеюсь, является концептуальным вопросом.

Заранее спасибо! Brian

1 Ответ

1 голос
/ 13 января 2011

Я бы рассмотрел переход к структуре планирования задач вместо того, чтобы полагаться на ручное манипулирование таймерами, если вы работаете над чем-то связанным со SCADA.Простая отправная точка - это что-то похожее на классы hardcodet.Sheduling , и вы можете перейти к чему-то вроде зверя Quartz .Большинство этих типов фреймворков предоставят вам возможность приостановить и возобновить запланированные действия.

Если я работаю с Modbus, я обычно сохраняю локальный кэш значений регистра и вносю изменения в любое значение.событие изменения.Это дает вам преимущество, заключающееся в том, что вы можете реализовывать такие вещи, как обновление значений вручную, не влияя на планирование вашего процесса и проверку мертвой зоны при оценке вашего ответа на опрос.Это оказалось побочным эффектом реализации опрашиваемого протокола для подмножества интерфейса OPC DA.

...