нулевые значения в списке <string>при добавлении и удалении в нескольких потоках - PullRequest
5 голосов
/ 25 февраля 2020

Я знаю, что C# System.Collections.Generi c .List не является потокобезопасным. Но мне интересно, почему этот фрагмент кода генерирует нулевые значения.

Task.Run(() =>
{
    for (var i = 0; i < 10; i++)
    {
        var str = $"Test {i}";
        list.Add(str);

        if (i == 9)
        {
            i = 0;
        }
    }
});

Task.Run(() =>
{
    while (true)
    {
        list.Remove("Test 1");
        list.Remove("Test 2");
        list.Remove("Test 3");
        list.Remove("Test 4");
        list.Remove("Test 5");
        list.Remove("Test 6");
        list.Remove("Test 7");
        list.Remove("Test 8");
        list.Remove("Test 9");
    }
});

Это часть списка через несколько секунд:

enter image description here

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

Ответы [ 2 ]

4 голосов
/ 25 февраля 2020

List<T> не является поточно-ориентированным, за исключением N чтений и нулевых записей; любое ненулевое число записей наряду с чем-либо еще не поддерживается, и такое поведение полностью не определено. Если вам нужен параллелизм: либо добавьте синхронизацию, либо используйте тип параллельной коллекции.

3 голосов
/ 25 февраля 2020

в дополнение к @ Mar c Gravell answer.

но я не понимаю, как генерируются эти нулевые значения

Первый поток непрерывно добавляет "Test {i}". Однако следующий поток удаляет "Test {i}". Следовательно, эти нулевые значения являются результатом действия удаления следующего потока.

Стоит сказать, что следующий "Test {i}" не будет заменен удаленным, а добавлен в конце шаблона c collection.

Окончательный результат будет выглядеть следующим образом:

Test 1 null Test 3 null null Test 6 .... Test 1 Test 2 null null Test 6 ...  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...