CountDownEvent не будет ждать, пока все сигналы не будут вызваны
Я смотрю на этом сайте темы. Я играл с кодом, чтобы ответить на вопрос "Останавливает ли CountdownEvent все потоки?" я получил ответ "нет". Тогда я решил поиграть с номером, который передается в CountdownEvent. Вот мой код
namespace ThreadPractice
{
class Program
{
static CountdownEvent CountDown = new CountdownEvent(4);
static void Main()
{
new Thread(() => SaySomething("I am Thread one.")).Start();
new Thread(() => SaySomething("I am thread two.")).Start();
new Thread(() => SaySomethingElse("Hello From a different Thread")).Start();
new Thread(() => SaySomething("I am Thread Three.")).Start();
CountDown.Wait();
Console.Read();
}
static void SaySomething(string Something)
{
Thread.Sleep(1000);
Console.WriteLine(Something);
CountDown.Signal();
}
static void SaySomethingElse(string SomethingElse)
{
Thread.Sleep(1000);
Console.WriteLine(SomethingElse);
}
}
}
Я ожидаю, что поток, который вызывает SaySomethingELse() для выполнения, но другие потоки также выполняются, даже если были вызваны только четыре сигнала.
Почему это так?
Спасибо,
dhoehna
2 ответа
Мне кажется, что у тебя есть Signal
а также Wait
неправильный путь. Если вы хотите SaySomething
звонки для ожидания обратного отсчета до 0, вы должны звонить Wait
, Вот пример:
using System;
using System.Threading;
namespace ThreadPractice
{
class Program
{
static CountdownEvent CountDown = new CountdownEvent(4);
static void Main()
{
new Thread(() => SaySomething("I am Thread one.")).Start();
new Thread(() => SaySomething("I am thread two.")).Start();
new Thread(() => SaySomethingElse("Hello From a different Thread")).Start();
new Thread(() => SaySomething("I am Thread Three.")).Start();
for (int i = 0; i < 4; i++)
{
Console.WriteLine("Calling Signal (time #{0})", i);
CountDown.Signal();
Thread.Sleep(1000);
}
Console.WriteLine("Done");
}
static void SaySomething(string Something)
{
CountDown.Wait();
Console.WriteLine(Something);
}
static void SaySomethingElse(string SomethingElse)
{
Thread.Sleep(1000);
Console.WriteLine(SomethingElse);
}
}
}
Выход:
Calling Signal (time #0)
Hello From a different Thread
Calling Signal (time #1)
Calling Signal (time #2)
Calling Signal (time #3)
I am Thread one.
I am Thread Three.
I am thread two.
Done
Хммм... мне кажется, что вы хотите дождаться окончания всех потоков, прежде чем продолжить в основном потоке. Если это так, вы забыли Signal() в SaySomethingElse(). Это не позволяет CountDown.CurrentCount достигнуть 0 (ноль), и поэтому ваш основной поток "застрял". Вы устанавливаете его на 4, а он уменьшается только до 1 (одного). Исправить это, и вы должны получить желаемое? Результаты:
class Program
{
static CountdownEvent CountDown = new CountdownEvent(4);
static void Main()
{
new Thread(() => SaySomething("I am Thread one.")).Start();
new Thread(() => SaySomething("I am thread two.")).Start();
new Thread(() => SaySomethingElse("Hello From a different Thread")).Start();
new Thread(() => SaySomething("I am Thread Three.")).Start();
CountDown.Wait();
Console.WriteLine("Done!");
Console.Read();
}
static void SaySomething(string Something)
{
Thread.Sleep(1000);
Console.WriteLine(Something);
CountDown.Signal();
}
static void SaySomethingElse(string SomethingElse)
{
Thread.Sleep(1000);
Console.WriteLine(SomethingElse);
CountDown.Signal();
}
}
Выход:
I am Thread one.
I am thread two.
Hello From a different Thread
I am Thread Three.
Done!