Я пытаюсь создать список подписки. Давайте рассмотрим пример:Лучшая структура данных для потокового списка подписки?
список издателей, каждый из которых имеет список журналов, каждый из которых имеет список абонентов
Publishers -> Журналы -> Подписчики
Имеет смысл использовать из словаря в словаре в словаре в C#. Можно ли это сделать без блокировки всей структуры при добавлении/удалении абонента без условий гонки?
Также код очень быстро запутался в C#, что заставляет меня думать, что я не пойду по правильному пути. Есть ли более простой способ сделать это? Вот конструктор и метод подписки:
Примечания: Код использует Источник, Тип Абонент вместо имен выше
Источника ---> Тип ---> Абонента
public class SubscriptionCollection<SourceT, TypeT, SubscriberT>
{
// Race conditions here I'm sure! Not locking anything yet but should revisit at some point
ConcurrentDictionary<SourceT, ConcurrentDictionary<TypeT, ConcurrentDictionary<SubscriberT, SubscriptionInfo>>> SourceTypeSubs;
public SubscriptionCollection()
{
SourceTypeSubs = new ConcurrentDictionary<SourceT, ConcurrentDictionary<TypeT, ConcurrentDictionary<SubscriberT, SubscriptionInfo>>>();
}
public void Subscribe(SourceT sourceT, TypeT typeT, SubscriberT subT) {
ConcurrentDictionary<TypeT, ConcurrentDictionary<SubscriberT, SubscriptionInfo>> typesANDsubs;
if (SourceTypeSubs.TryGetValue(sourceT, out typesANDsubs))
{
ConcurrentDictionary<SubscriberT, SubscriptionInfo> subs;
if (typesANDsubs.TryGetValue(typeT, out subs))
{
SubscriptionInfo subInfo;
if (subs.TryGetValue(subT, out subInfo))
{
// Subscription already exists - do nothing
}
else
{
subs.TryAdd(subT, new SubscriptionInfo());
}
}
else
{
// This type does not exist - first add type, then subscription
var newType = new ConcurrentDictionary<SubscriberT, SubscriptionInfo>();
newType.TryAdd(subT, new SubscriptionInfo());
typesANDsubs.TryAdd(typeT, newType);
}
}
else
{
// this source does not exist - first add source, then type, then subscriptions
var newSource = new ConcurrentDictionary<TypeT, ConcurrentDictionary<SubscriberT, SubscriptionInfo>>();
var newType = new ConcurrentDictionary<SubscriberT, SubscriptionInfo>();
newType.TryAdd(subT, new SubscriptionInfo());
newSource.TryAdd(typeT, newType);
SourceTypeSubs.TryAdd(sourceT, newSource);
};
}
вопрос C# -специфический, или вы ищете подход, который может быть использован в любом месте? – svick
Anywhere really .. тогда я могу адаптировать его к C# –
Я спрашиваю, потому что, если вопрос является C# -специфичным, то есть классы непосредственно в .Net framework, которые вы могли бы использовать. – svick