Monitor.Pulse() вызывает тупик с дочерними элементамиC#

Место общения программистов C#
Ответить
Anonymous
 Monitor.Pulse() вызывает тупик с дочерними элементами

Сообщение Anonymous »

У меня возникла проблема, которую я свел к этому минимальному тестовому примеру, но до сих пор не понимаю, почему она не работает должным образом. Код здесь прост: родительский поток получает блокировку, затем запускает дочерний поток, затем освобождает блокировку, запуская для него ожидание. Затем дочерний поток, который был заблокирован той же блокировкой, продолжает работу, освобождает родительский поток и затем приостанавливается на пять секунд.

Код: Выделить всё

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() — дочерний элемент наверняка ждал блокировки.

Что это, это баг? Есть ли обходной путь?

Подробнее здесь: https://stackoverflow.com/questions/291 ... hild-items
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»