この最小限のテストケースに縮小した問題がありましたが、それでも正しく機能しない理由がわかりません。ここでのコードは単純です。親スレッドがロックを取得し、次に子を起動し、次に 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()
しかし、私は親に呼び出しを設定することでそれを反証しました— 子供は確かにロックを待っていました.
これは何ですか、それはバグですか?回避策はありますか?