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!
Другие вопросы по тегам