C#:Monitor.Pulse()不起作用

时间:2015-03-19 11:02:58

标签: c# multithreading pulse

我遇到了一个问题,我将其缩减到这个最小的测试用例,但我仍然不明白为什么它不能正常工作。这里的代码很简单:父线程获取一个锁,然后启动一个子,然后通过启动await来释放锁。然后锁定在同一个锁上的子线程继续进行,释放父进程,然后休眠5秒钟。

using System.Threading;
using System;
using System.IO;
using System.Diagnostics;

namespace Test
{
    class MainClass
    {
        public static void Main(string[] args)
        {
            Object waitForThrToStart = new Object();
            lock (waitForThrToStart)
            {
                new Thread(() =>
                {
                    lock (waitForThrToStart)
                    {
                        Debug.WriteLine("2. Child: free the parent");
                        Monitor.Pulse(waitForThrToStart);
                        Debug.WriteLine("3. Child: pulsed ☺ Now sleep");
                        Thread.Sleep(5000);
                        Debug.WriteLine("5. Child: time out");
                    }
                }).Start();
                Debug.WriteLine("1. Parent: waiting");
                Monitor.Wait(waitForThrToStart);
                Debug.WriteLine("4. Parent: awoke, exiting now");
            }
        }
    }
}

除了......它没有用之外它很好。父母只在五秒后释放,当孩子退出时,你可以在输出中看到它:

1. Parent: waiting
2. Child: free the parent
3. Child: pulsed ☺ Now sleep
5. Child: time out
4. Parent: awoke, exiting now

我甚至尝试使用Monitor.PulseAll(),但没有改变任何东西。此外,我想也许是因为一些奇怪的原因,孩子得到了一个对象的副本,因此他们正在处理不同的变量。但我通过在父母中设置Sleep()电话来反驳它 - 孩子肯定在等待锁定。

这是什么,是一个错误?有没有解决方法?

1 个答案:

答案 0 :(得分:3)

您在儿童中使用显示器,但您也已将其锁定。 Wait只有在您释放子线程中的锁定后才会返回,此时需要在返回之前重新获取锁定。