Подтвердить что ты не робот

Почему эта программа по ошибке? "Метод синхронизации объектов был вызван из несинхронизированного блока кода"

Что не так с этим кодом? Я получаю "Метод синхронизации объектов" вызывается из несинхронизированного блока кода ". Я нашел один результат в google, который сказал, что я могу освободить мьютекс перед блокировкой, но в соответствии с моим результатом это не так. Вот код мьютекса без другого кода между ними.

-edit- извините, парни, неправильная паста.

Мой вывод

1W
1W
2W

код

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

namespace sqliteTest
{
    class Program
    {
        static volatile Mutex mut1 = new Mutex();
        static volatile Mutex mut2 = new Mutex();
        static void Main(string[] args)
        {
            mut1.WaitOne(); Console.WriteLine("1W");
            Thread oThread = new Thread(new ThreadStart(fn2));
            oThread.Start();
            mut1.WaitOne(); Console.WriteLine("1W");
            update(0);
        }
        static void fn2()
        {
            mut2.WaitOne(); Console.WriteLine("2W");
            mut1.ReleaseMutex(); Console.WriteLine("1R");
            mut2.WaitOne(); Console.WriteLine("2W");
            update(1);
            mut1.ReleaseMutex(); Console.WriteLine("1R");
        }
        static void update(int t)
        {
            mut2.ReleaseMutex(); Console.WriteLine("2R");
            if (t == 0)
            {
                mut1.WaitOne();
                Console.WriteLine("1W");
            }
        }
    }
}
4b9b3361

Ответ 1

Это не замечательное сообщение об ошибке, которое производит Windows. На самом деле это означает, что вы вызываете ReleaseMutex на мьютексе, которого у вас нет. Вы пройдете первое исключение с помощью

static volatile Mutex mut2 = new Mutex(true);

Но тогда он будет умирать внутри потока, когда он вызывает ReleaseMutex на mut1, который он не имеет. Не уверен, что вы пытаетесь сделать, код не имеет для меня никакого смысла.

Ответ 2

В вашем коде есть ряд проблем. Основной поток запускает новый поток, а затем вызывает обновление. При обновлении он пытается разблокировать mutex2, но он еще не заблокировал mutex2, поэтому это не удается с исключением.

Даже если эта ошибка исправлена, другой поток также обречен на провал. Он попытается освободить mutex1, прежде чем он заблокирует его.

Что вы пытаетесь сделать здесь? Вы сбиваете с толку Mutex с AutoResetEvent?

Также я предполагаю, что эти две строки являются ошибкой копирования/вставки, потому что они появляются дважды:

        mut2.WaitOne(); Console.WriteLine("2W");
        mut1.ReleaseMutex(); Console.WriteLine("1R");

Ответ 3

Да, другие правы: Этот код не имеет никакого смысла.

Но поскольку эта страница имеет высокий рейтинг в Google (хотя это не помогает), я перенаправляю всех поисковиков на этот отличный сайт о синхронизации потоков:

http://www.albahari.com/threading/part2.aspx

Elmü

Ответ 4

Просто хотел опубликовать еще один странный сценарий, с которым я столкнулся, поскольку он может помочь другим. Я получал это исключение при открытии проекта в Visual Studio 2010 С# express. Теперь мой проект содержит некоторые потоки, но я бы не ожидал, что он столкнется с Visual Studio при загрузке кода, что и происходит именно так.

Заметка о моем коде: я использую MethodInvoker и BeginInvoke (после проверки InvokeRequired), вызываемого в потоке STA ([STAThreadAttribute]). Опять же, этот код никогда не получит шанс даже запустить. Visual Studio Express может привести к сбою только загрузки проекта. Кроме того, все это началось после того, как я получил странное исключение FileNotFoundException, которое также сбило VS, когда оно утверждало, что не может найти ссылку. Я исправил это, в конечном счете, полностью удалив ссылку и все ее использование из кода, построив, закрыв VS, снова открыв его и открыв решение, чтобы только тогда начать атаковать эту загадочную ошибку. В этом проекте нет мутексов или мониторов или связанных с ранее удаленной ссылкой (пользовательская библиотека, которая просто рисует некоторые графики).

После значительных исследований (googling), где я нашел массу интересной информации, которая не имела никакого отношения к сбою VS, я, наконец, решил просто попробовать и открыть решение в Visual Studio 2010 Professional, чтобы узнать, не сработает ли это как Что ж. Это не так. Я сделал пару изменений токена в настройках кода и проекта, создал и сохранил все, отключил его, и теперь я могу снова открыть решение в Visual Studio Express без каких-либо ошибок! Очень странно. Не знаю, поможет ли это кому-либо, поскольку это немного похоже на возможности для этого исключения. Я подозреваю, что у меня была проблема с моим реестром, поскольку в прошлом я столкнулся с несколькими любопытными ситуациями с Visual Studio, и мой реестр не ладил, все из тех, что влияли на то, как мои проекты загружаются, даже заставляя меня восстанавливать мой реестр, запустить очиститель реестра и перезагрузиться, чтобы вернуть нормальное поведение.