简体   繁体   中英

“Object synchronization method was called from an unsynchronized block of code” using monitors and lock

I've searched on the existing posts about this error but I not resolved my problem with what I found there.

I'm implementing the consumer-producer problem using a lock and 2 objects for monitors. But when I run the code a get the following error 'Object synchronization method was called from an unsynchronized block of code.'. I've atached my code bellow:

ProducerConsumer.cs :

using System;
using System.Collections.Generic;
using System.Threading;

namespace ProducerConsumer
{
    public class ProducerConsumer
    {
        private Queue<int> _items;
        private object _lockObject;
        private object _condProd;
        private object _condCons;

        public ProducerConsumer()
        {
            _items = new Queue<int>();
            _lockObject = new object();
            _condProd = new object();
            _condCons = new object();
        }

        public void Produce(string name)
        {
            int count = 1;
            bool produced = false;

            while (true)
            {     
                if (produced == false)
                {
                    Console.WriteLine(name + "/Produced: " + count);
                    Thread.Sleep(50);
                    produced = true;
                    count++;
                }

                lock (_lockObject)
                {
                    while (_items.Count == 5)
                    {
                        Monitor.Wait(_condProd);
                    }

                    _items.Enqueue(count);
                }
                Monitor.Pulse(_condCons);

                produced = false;

            }
        }

        public void Consume(string name)
        {
            int count = 0;
            while (true)
            {
                lock (_lockObject)
                {
                    while (_items.Count == 0)
                    {
                        Monitor.Wait(_condCons);
                    }

                    count = _items.Dequeue();
                    Console.WriteLine(name + "/Scos din lista: " + count);
                }

                Monitor.Pulse(_condProd);
            }
        }
    }
}

Program.cs :

using System;
using System.Threading.Tasks;

namespace ProducerConsumer
{
    class Program
    {
        static void Main(string[] args)
        {
            ProducerConsumer pc = new ProducerConsumer();
            Task p = Task.Factory.StartNew(() => pc.Produce("Producer 1"));
            Task c = Task.Factory.StartNew(() => pc.Consume("Consumer 1"));
            Task.WaitAll(p, c);
            Console.ReadKey();
        }
    }
}

Please help me to understand why I get this error and how I can resolve it, I'm new in the threading section of the C# language. Thank you in advance.

To call Monitor.Pulse(_condCons); you need to hold the lock on _condCons ; to call Monitor.Wait(_condProd); you need to hold the lock on _condProd . It isn't clear that the wait is locking on the right object, and the pulse doesn't seem to be locking on any object.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM