1

この最小限のテストケースに縮小した問題がありましたが、それでも正しく機能しない理由がわかりません。ここでのコードは単純です。親スレッドがロックを取得し、次に子を起動し、次に 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");
            }
        }
    }
}

それ以外は問題ありません… 機能しません。親は 5 秒後にのみ解放され、子が終了すると、出力に表示される場合があります。

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()しかし、私は親に呼び出しを設定することでそれを反証しました— 子供は確かにロックを待っていました.

これは何ですか、それはバグですか?回避策はありますか?

4

1 に答える 1

3

あなたは子供のモニターを脈動させていますが、それもロックしています。はWait、子スレッドでロックを解放した後にのみ戻ります。その時点で、戻る前にロックを再取得する必要があります。

于 2015-03-19T11:09:42.627 に答える