Исключение: метод синхронизации объекта был вызван из несинхронизированного блока кода - PullRequest
1 голос
/ 23 ноября 2011

У меня есть несколько потоков, которые пишут в один и тот же int.Каждый поток увеличивает целочисленное значение.Какой простой способ синхронизации операции приращения.Оператор блокировки работает только на объекте, поэтому я не могу его использовать.Я пробовал также следующее:

static int number=0;

static void Main(string[] args)
    {
        ThreadStart ts = new ThreadStart(strtThread);
        new Thread(ts).Start();
        new Thread(ts).Start();
        new Thread(ts).Start();
        new Thread(ts).Start();
        new Thread(ts).Start();
        new Thread(ts).Start();
        Console.ReadLine();
    }

    public static void strtThread()
    {
        bool lockTaken = false;

        Monitor.Enter(number,ref lockTaken);
        try
        {
            Random rd = new Random();
            int ee = rd.Next(1000);
            Console.WriteLine(ee);
            Thread.Sleep(ee);
            number++;
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
        finally 
        {
            if (lockTaken)
            {
             Monitor.Exit(number);
            }

        }
    }

Это дает мне следующую ошибку:

Метод синхронизации объекта был вызван из несинхронизированного блока кода.

Ответы [ 3 ]

5 голосов
/ 23 ноября 2011

Вы можете использовать метод Interlocked.Increment для автоматического увеличения целого числа без блокировки:

public static void strtThread()
{
    Interlocked.Increment(ref number);
}

Если у вас есть несколько операторов, вы можете создать объект экземпляр, который вы можете заблокировать :

private static int number = 0;
private static readonly object gate = new object();

public static void strtThread()
{
    lock (gate)
    {
       number++;
    }    
}
2 голосов
/ 23 ноября 2011

Interlocked.Increment обеспечивает приращение атома.Класс Interlocked в общем "обеспечивает атомарные операции для переменных, которые совместно используются несколькими потоками."

2 голосов
/ 23 ноября 2011

Зачем вам беспокоиться с number? Я думаю, что это проблема. Попробуйте это:

static Object locking = new Object();

static void Main(string[] args)
    {
        ThreadStart ts = new ThreadStart(strtThread);
        new Thread(ts).Start();
        new Thread(ts).Start();
        new Thread(ts).Start();
        new Thread(ts).Start();
        new Thread(ts).Start();
        new Thread(ts).Start();
        Console.ReadLine();
    }

    public static void strtThread()
    {
        lock(locking) {
            try
            {
                Random rd = new Random();
                int ee = rd.Next(1000);
                Console.WriteLine(ee);
                Thread.Sleep(ee);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...