Пользуюсь в многопоточном проекте таким кодом:
N разных потоков парсят одну и ту же страницу, в ожидании появления на ней благоприятного события с интересующим значением var. Это по типу того, как несколько разных таксистов ждут клиента на пятачке. И вот клиент приходит (благоприятное событие), а ехать клиенту нужно на улицу Строителей (значение var).
Дальше идет проверка через этот код, не взял ли уже другой параллельный поток это значение в работу.
Если не взял (значения нет в List) - добавляем значение var в лист, после чего поток работает с этим значением дальше согласно проекту.
Если взял (уже есть значение в List) значит возвращаем "no" и просто ждем, когда появятся другие значения var для проверки.
Так вот, несмотря на то, что тут используется lock (SyncObjects.ListSyncer), иногда случается так, что два разных потока берут в работу одно и то же значение var.
Причем, согласно трассировке, происходит это почти в одно и то же время с разницей в доли секунды, причем не видно чтобы была какая-то задержка, которая как я понимаю должна быть, ведь список все-таки должен лочиться:
Вот 1-й поток проверяет:
04-05-2022 01:09:56.3927|Good|5d71afc5-6f4e-4c8c-8200-5180c4716687|0
А вот 2-й проверяет и тоже берет значение в работу:
04-05-2022 01:09:56.4978|Good|5d71afc5-6f4e-4c8c-8200-5180c4716687|0
В общем, хочу поинтересоваться, отчего такое может быть. Нормально ли вообще такое поведение?
C#:
// берем из переменной текст, который надо искать
var textContains = project.Variables["var"].Value;
// получаем список, в котором будем искать
var sourceList = project.Lists["List"];
// ищем в каждой строчке в списке
lock (SyncObjects.ListSyncer)
{
for (int i = 0; i < sourceList.Count; i++)
{
// читаем строку из списка
var str = sourceList[i];
// проверяем содержание текста в строке, если есть совпадение, возвращаем "no"
if (str.Contains(textContains))
return "no";
//return null; // если раскомментировать эту строку, а предыдущую закомментировать (или удалить), выход будет по красной ветке (как вариант)
}
}
// если нет совпадений, добавляем строку в список
sourceList.Add(textContains);
Дальше идет проверка через этот код, не взял ли уже другой параллельный поток это значение в работу.
Если не взял (значения нет в List) - добавляем значение var в лист, после чего поток работает с этим значением дальше согласно проекту.
Если взял (уже есть значение в List) значит возвращаем "no" и просто ждем, когда появятся другие значения var для проверки.
Так вот, несмотря на то, что тут используется lock (SyncObjects.ListSyncer), иногда случается так, что два разных потока берут в работу одно и то же значение var.
Причем, согласно трассировке, происходит это почти в одно и то же время с разницей в доли секунды, причем не видно чтобы была какая-то задержка, которая как я понимаю должна быть, ведь список все-таки должен лочиться:
Вот 1-й поток проверяет:
04-05-2022 01:09:56.3927|Good|5d71afc5-6f4e-4c8c-8200-5180c4716687|0
А вот 2-й проверяет и тоже берет значение в работу:
04-05-2022 01:09:56.4978|Good|5d71afc5-6f4e-4c8c-8200-5180c4716687|0
В общем, хочу поинтересоваться, отчего такое может быть. Нормально ли вообще такое поведение?