Конфликт при Блокировке двух методов так, чтобы только 1 Поток мог использовать блокировку

У меня есть проблема относительно многопоточности и вставки объекта к Словарю. Следующая ситуация - то, что я - encoutering, когда insertingen подвергает с дублирующимся идентификатором:

    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
            }
        }
    }

Я заблокировал оба метода, но блокировка, кажется, не работает... Кажется, что два потока оба вводят блокировку в различные методы. Я упускаю суть использования блокировки ()? Какая-либо идея о том, как я должен реализовать это правильно? Важная заметка на полях, ProcessThreads () метод называет каждую секунду Таймер (bufferChecker).

1
задан Bas 25 June 2010 в 13:54
поделиться

1 ответ

Вы запускаете новый поток в каждом методе - эти новые потоки не будут иметь (или запрашивать) блокировку.

Таким образом, хотя только один из ProcessThreads или TryToExecute может эффективно выполняться одновременно, вы не можете контролировать биты в лямбда-выражениях. Если они также требуют взаимного исключения, вам нужно поместить в эти лямбды оператор lock .

2
ответ дан 2 September 2019 в 23:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: