Используйте LINQ ToDictionary с ConcurrentDictionary
Я использую словарь для сбора событий в многопоточном приложении, использую блокировку при добавлении события и не использую его при поиске. Каждый час или около того я запускаю очистку событий старше определенного времени. Очень просто и все работает.
Я хотел бы перейти к ConcurrentDictionary, чтобы удалить блокировки, и я подумал, что мне просто нужно добавить "Concurrent" и изменить Add на TryAdd. Но потом я понес ошибку: LINQ возвращает только ToDictionary. Я, конечно, не могу использовать LINQ, но мне было интересно узнать, могу ли я что-то сделать, чтобы сохранить его. И что более важно, есть что-то, что я еще должен рассмотреть, прежде чем перейти к ConcurrentDictionry?
public class messageResult
{
public Result result;
public DateTime receivedTime;
}
public Dictionary<Guid, messageResult> events = new Dictionary<Guid, messageResult>();
lock (events)
{
events = events.Where(p => p.Value.receivedTime >= t).ToDictionary(p => p.Key, p => p.Value);
}
Спасибо
2 ответа
Похоже, ToDictionary
Метод расширения не так сложен, и вы можете создать свою собственную версию.
Но учтите, что ToDictionary
возвращает новый объект, в то время как вы хотели бы иметь один словарь и делиться им между своими потоками.
Вы не должны блокировать изменяемую переменную (и вы также меняете фактическую ссылку на events
), создайте приватную переменную только для чтения и используйте ее для блокировки.
ToDictionary возвращает новый экземпляр... который отличается от вашего общего экземпляра.
Вы хотите изменить свой общий экземпляр и должны написать код, который делает это:
foreach(var kvp in events.Where(...).ToList())
{
var val = kvp.Value;
events.TryRemove(kvp.Key out val);
}