Как получить значения List при вмешательстве других потоков?
Есть несколько потоков, которые добавляют значения в:
public static List<TimeSpan> SpisokVremeni { get; set; }
А есть поток, который хочет перебрать этот список SpisokVremeni и скопировать значения в свой локальный список.
Но вот при переборе этого SpisokVremeni в foreach, возникают проблемы, другие потоки добавляют значения и естественно вылетает исключение.
Как такой момент обойти ? Как получить копию без исключений ?
Пробовал так, но на потоки которые добавляют значения в SpisokVremeni - это никак не повлияло:
List<TimeSpan> kopiyaSpiskaVremeni = new();
lock (locker)
{
foreach (TimeSpan vremya in MyClass.SpisokVremeni)
{
kopiyaSpiskaVremeni.Add(vremya);
}
}
return kopiyaSpiskaVremeni;
Ответы (1 шт):
Синхронизация — это кооперативная задача. Все, кто работают с разделяемыми данными, должны придерживаться протокола общения.
В простом случае это означает, что блокировку должен брать как читающий код на время чтения, так и записывающий код на время записи. Иначе смысла в блокировке нет никакого.
Старайтесь делать под блокировкой как можно меньше. Например, если вам нужно добыть данные из какого-то другого источника (например, из сети или из файла), и записать добытые данные в список, добывайте данные без блокировки, а блокировку берите только на время записи.
Кстати, ваш код можно упростить до такого:
lock (locker)
return MyClass.SpisokVremeni.ToList();
Но, как вы уже сами выяснили, вам нужно использовать блокировку (тем же объектом locker!) и там, где происходит запись.