У меня проблема с многопоточностью и вставкой элемента в словарь.Следующая ситуация - это то, что я приветствую, когда вставляю объекты с дублирующими идентификаторами:
private static readonly Timer bufferChecker;
private static readonly List<SubjectStartRulePair> inBuffer;
private static readonly IDictionary<Guid, Subject> beingProcessed;
private static readonly object objLock;
static InBuffer()
{
objLock = new object();
inBuffer = new List<SubjectStartRulePair>();
beingProcessed = new Dictionary<Guid, Subject>();
bufferChecker = new Timer(x => ProcessThreads(), null, 1000, 1000);
}
public static void ProcessThreads()
{
lock(objLock)
{
var bufferedItems = inBuffer.OrderBy(x => x.QueuedTime);
foreach (var item in bufferedItems)
{
if (!beingProcessed.ContainsKey(item.Subject.SubjectId)) //Important check which validates if there is already a Thread running
{
var thread = new Thread(
x =>
{
//Thread #2 is here and runs into duplicate Key
beingProcessed.Add(item.Subject.SubjectId, item.Subject);
item.StartRule(item.Subject);
beingProcessed.Remove(item.Subject.SubjectId);
});
thread.Start();
inBuffer.Remove(item);
}
}
}
}
public static void TryToExecute(Subject subject, IBusinessRule rule)
{
lock (objLock)
{
if (beingProcessed.ContainsKey(subject.SubjectId)) //Important check which validates if there is already a Thread running
{
inBuffer.Add(
new SubjectStartRulePair
{
QueuedTime = DateTime.Now,
Subject = subject,
StartRule = (x =>
{
rule.RunChildren(subject);
return true;
})
}
);
}
else
{
var thread = new Thread(
x =>
{
beingProcessed.Add(subject.SubjectId, subject);
rule.RunChildren(subject);
beingProcessed.Remove(subject.SubjectId);
});
thread.Start(); //Thread #1 is here
}
}
}
Я заблокировал оба метода, но блокировка не работает ... Кажется, что оба потока входят вблокировка на разные методы.Я пропускаю смысл использования lock ()?Любая идея о том, как я должен реализовать это правильно?Важное замечание: метод ProcessThreads () вызывается Timer (bufferChecker) каждую секунду.