为什么这个程序出错? `对象同步方法是从一个不同步的代码块调用的

时间:2009-12-12 22:30:14

标签: c# .net synchronization mutex

这段代码有什么问题?我得到一个'对象同步方法是从一个不同步的代码块调用'。我在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");
            }
        }
    }
}

4 个答案:

答案 0 :(得分:22)

这不是一个很好的错误消息,Windows生成它。它的真正含义是你在一个你不拥有的互斥锁上调用ReleaseMutex。你将通过

超越第一个例外
static volatile Mutex mut2 = new Mutex(true);

但是当它在mut1上调用ReleaseMutex时它将在线程内部死亡,而它不属于它。不确定你要做什么,代码对我来说没有多大意义。

答案 1 :(得分:5)

是的,其他人是对的: 这段代码没有任何意义。

但由于此页面在Google中排名较高(虽然没有帮助),我将所有搜索者重定向到这个关于线程同步的网站:

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

Elmü

答案 2 :(得分:4)

您的代码似乎有很多问题。主线程启动一个新线程,然后调用update。在更新中它尝试解锁mutex2,但它还没有锁定mutex2,因此失败并出现异常。

即使修复了这个错误,另一个线程也同样注定要失败。它会在锁定之前尝试释放mutex1。

你想在这做什么?您是否将Mutex与AutoResetEvent混淆了?

另外我猜这两行都是复制/粘贴错误,因为它们出现了两次:

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

答案 3 :(得分:0)

只是想发布我遇到的另一个奇怪的场景,因为它可能会帮助其他人。在Visual Studio 2010 C#express中打开一个项目时,我遇到了这个异常。现在我的项目确实包含一些线程,但我不希望它在加载代码时崩溃Visual Studio,这正是发生的事情。

关于我的代码的注释:我正在使用MethodInvoker和BeginInvoke(在检查InvokeRequired之后)调用STA线程([STAThreadAttribute])。同样,这段代码永远不会有机会运行。只需加载项目,Visual Studio Express就会崩溃。此外,这一切都开始发生在我得到一个奇怪的FileNotFoundException同样崩溃VS时声称它无法找到引用。我通过最终从代码中完全删除引用及其所有用法来修复它,构建,关闭VS,再次打开它并打开解决方案,然后才开始遇到这个神秘的错误。此项目中没有互斥锁或监视器,或与之前删除的引用相关联(仅绘制一些图形的自定义库)。

经过大量研究(谷歌搜索),我发现了大量与VS崩溃无关的有趣信息,我最终决定尝试在Visual Studio 2010 Professional中打开解决方案,看看它是否会崩溃好。它没有。我对代码和项目设置进行了一些令牌更改,构建并保存了所有内容,将其关闭,现在我可以在Visual Studio Express中再次打开解决方案而不会出现任何错误!很奇怪。不知道这是否会对任何人有所帮助,因为这似乎有点在这个例外的可能性边缘。我怀疑我的注册表中存在所有问题,因为过去我遇到过一些奇怪的情况,Visual Studio和我的注册表没有相关,所有这些都会影响我的项目加载,甚至迫使我恢复我的注册表,运行注册表清理程序,然后重新启动以恢复正常行为。