Как получить значения 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 шт):

Автор решения: VladD

Синхронизация — это кооперативная задача. Все, кто работают с разделяемыми данными, должны придерживаться протокола общения.

В простом случае это означает, что блокировку должен брать как читающий код на время чтения, так и записывающий код на время записи. Иначе смысла в блокировке нет никакого.


Старайтесь делать под блокировкой как можно меньше. Например, если вам нужно добыть данные из какого-то другого источника (например, из сети или из файла), и записать добытые данные в список, добывайте данные без блокировки, а блокировку берите только на время записи.


Кстати, ваш код можно упростить до такого:

lock (locker)
    return MyClass.SpisokVremeni.ToList();

Но, как вы уже сами выяснили, вам нужно использовать блокировку (тем же объектом locker!) и там, где происходит запись.

→ Ссылка