有人可以给我一个如何在C#中使用System.Monitor的简单示例吗?

时间:2008-10-23 08:27:07

标签: c# multithreading

我发现System.Monitor非常混乱,虽然我理解线程,锁,死锁,竞争条件,餐饮哲学家和所有爵士乐。通常我使用ManualResetEvent()来进行线程间协调,但我知道这是一个重量级的内核对象,System.Monitor(Enter / Pulse等)效率更高。我用谷歌搜索和谷歌搜索,但找不到一个明智的例子。

如果SO工作人员可以向我解释这个可能很棒的结构,我将非常感激: - )

2 个答案:

答案 0 :(得分:8)

这是一个非常简单的例子;对Wait的调用释放锁(允许Worker获取它)并将Main线程添加到锁对象的挂起队列中。然后Worker获取锁,并调用Pulse:这会将Main线程移动到锁对象的就绪队列中。当Worker 发布锁定时,Main可以恢复工作。

请注意lock(obj) {...}只是try / finally块中Monitor.Enter / Monitor.Exit的编译器糖果。

[编辑:我之前更改了示例以移动lock(sync),以避免错过脉冲的风险(不太可能)

    static void Main()
    {
        object sync = new object();
        lock (sync)
        {
            ThreadPool.QueueUserWorkItem(Worker, sync);
            Console.WriteLine("Main sleeping");

            // wait for the worker to tell us it is ready
            Monitor.Wait(sync);
            Console.WriteLine("Main woke up!");
        }
        Console.WriteLine("Press any key...");
        Console.ReadKey();
    }
    static void Worker(object sync)
    {
        Console.WriteLine("Worker started; about to sleep");
        Thread.Sleep(5000);
        Console.WriteLine("Worker about pulse");
        lock (sync)
        { // notify Main that we did something interesting
            Monitor.Pulse(sync);
            Console.WriteLine("Worker pulsed; about to release lock");
        }
        Console.WriteLine("Worker all done");
    }

答案 1 :(得分:3)

查看this part of my threading article是否有帮助......(该页面的后半部分)。它实现了一个生产者/消费者队列:当生产者在队列中生成某些东西(并发现它是空的 - 作为优化)时,它会激活监视器以唤醒任何等待的线程。当消费者试图从队列中消费但发现它为空时,它会在再次尝试之前等待一个脉冲。

或者,Joe Albahari's threading tutorial也有关于等待/脉冲的部分。

它与你习惯的WaitHandle非常相似 - 虽然坦率地说我发现比WaitHandles更容易让我头脑发热,主要是因为它与Java等待/通知非常相似,我“长大”了:)