C# cинхронизация потоков

207
24 января 2018, 12:49

Возникла проблема с синхронизацией потоков.
Общая схема упрощенно в следующем.
Есть ПК к которому подключены два устройства через 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);
    }  

то они, по-идее, будут блокировать друг-друга, но этого не нужно, т.к. они обновляют разные переменные.
Как этого избежать?

Answer 1

А чем вам не нравится обыкновенный 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, в котором вы будете передавать новые значения. Таким образом у вас разделяемые переменные совсем уйдут, а с ними и необходимость блокировки.

READ ALSO
C# Прием файла по сети

C# Прием файла по сети

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

248
Реализовать foreach для обобщенного класса

Реализовать foreach для обобщенного класса

Есть класс - реализация очереди через List

156
ASP.Net Core, как получить все выбранные значения тегов Select?

ASP.Net Core, как получить все выбранные значения тегов Select?

Предположим я на странице леплю формочку в которой несколько элементов select, вот такой код

243