Подтвердить что ты не робот

Является ли это правильным способом перебора Concurrentdictionary в С#

Я использую этот код только для примера. Предположим, у меня есть следующий класс Person.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace dictionaryDisplay
{
class Person
{
    public string FirstName { get; private set;}
    public string LastName { get; private set; }

    public Person(string firstName, string lastName)
    {
        this.FirstName = firstName;
        this.LastName = lastName;

    }

    public override string ToString()
    {
        return this.FirstName + " " + this.LastName;
    }
}

}

Основная программа

static void Main(string[] args)
    {
        ConcurrentDictionary<int, Person> personColl = new ConcurrentDictionary<int,   Person>();

        personColl.TryAdd(0, new Person("Dave","Howells"));
        personColl.TryAdd(1, new Person("Jastinder","Toor"));

        Person outPerson = null;
        personColl.TryRemove(0, out outPerson);


        //Is this safe to do?
        foreach (var display in personColl)
        {
            Console.WriteLine(display.Value);
        }





    }
  • Это безопасный способ повторения параллельного словаря? Если нет, то какой безопасный способ это сделать?

  • Предположим, что я хочу удалить объект Person из словаря. Я использую метод tryRemove, но что мне делать с объектом outper? удаленный Человек из словаря хранится в нем. Что мне делать с объектом outper, чтобы полностью очистить его?

4b9b3361

Ответ 1

- это безопасный способ повторения параллельного словаря? Если нет, то какой безопасный способ это сделать?

Да, он безопасен тем, что не будет генерировать исключение. Если элементы будут добавлены или удалены после запуска итерации, они могут быть или не быть включены в итерацию. Из GetEnumerator документации:

Перечислитель, возвращаемый из словаря, безопасен для одновременного использования с чтением и записью в словарь, однако он не представляет моментальный снимок словаря во времени. Содержимое, отображаемое через счетчик, может содержать изменения, внесенные в словарь после вызова GetEnumerator.

Далее:

Я использую метод tryRemove, но что мне делать с объектом outper?

Что бы вы ни хотели с ним, включая ничего. Вы можете просто перевести словарь в IDictionary<TKey, TValue> и вызвать Remove или просто использовать TryRemove и затем игнорировать переменную:

Person ignored;
dictionary.TryRemove(key, out ignored);

Нет понятия "очистка [объекта] полностью" - если у вас нет ссылок на него, это будет сбор мусора. Но в любом случае это не в словаре больше (по крайней мере, через этот ключ). Если вы не используете переменную (ignored выше) где-либо еще в коде, она не остановит объект от сбора мусора.

Ответ 2

Взгляните на эту статью.

TryRemove() was added to attempt atomic, safe removes.

    To safely attempt to remove a value we need to see if the key exists first, this checks for existence and removes under an atomic lock.

Так как TryRemove удалит элемент из коллекции, вам может понадобиться значение ключа.

Безопасно перебирать его с помощью foreach. Вы не получите исключение.