Возникла проблема с синхронизацией потоков.
Общая схема упрощенно в следующем.
Есть ПК к которому подключены два устройства через 2 Com-порта.
Из каждого устройства через свой порт в отдельном потоке читаются переменные (один порт - один поток, код одинаковый):
поток 1 - устройство 1 - переменные Val1, Val2
поток 2 - устройство 2 - переменные Val3, Val4
Третий поток - UI, читает Val1, Val2, Val3, Val4.
Вопрос:
Как обеспечить запрет чтения на время обновления переменной, но чтобы при этом поток 1 не блокировал поток 2.
Если сделать так в потоках 1 и 2:
if (port==1)
PortValues=...
else
PortValues=...
lock (thisLock)
{
//чтение из Com-порта ....
foreach(var v in PortValues)
v.Val = ReadFromComPort(port, v.Name);
}
то они, по-идее, будут блокировать друг-друга, но этого не нужно, т.к. они обновляют разные переменные.
Как этого избежать?
А чем вам не нравится обыкновенный lock?
Например, объявляем объекты для блокировки:
object port1lock = new object();
object port2lock = new object();
В потоке №1:
var (v1, v2) = readValues();
lock (port1lock)
(Val1, Val2) = (v1, v2);
В потоке №2:
var (v3, v4) = readValues();
lock (port2lock)
(Val3, Val4) = (v3, v4);
И в UI-потоке:
// объявить переменные v1, v2, v3, v4 ...
lock (port1lock) lock (port2lock)
(v1, v2, v3, v4) = (Val1, Val2, Val3, Val4)
С другой стороны, холостое чтение в UI-потоке — не лучшая идея. Поэтому, возможно, вам стоит при изменении значений, прочитанных из портов, отправлять из рабочих потоков в UI-поток event, в котором вы будете передавать новые значения. Таким образом у вас разделяемые переменные совсем уйдут, а с ними и необходимость блокировки.
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости