Какой лучший способ определить, что потоки остановлены?

StackOverflow https://stackoverflow.com/questions/3824107

Вопрос

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

ThreadPool.QueueUserWorkItem(new WaitCallback(delegate
{
    Thread1Running = true;

    try
    {
        while (running)
        {
            AutoReset1.WaitOne(TimeSpan.FromSeconds(30.0));

            if (running)
            {
                // do stuff
            }
        }
    }
    finally
    {
        Thread1Running = false;
    }
}));

Когда приходит время, чтобы закрыть мой сервис, чтобы остановиться, я просто установил в False и Set Call () на всех ауторесах. Это мгновенно сигнализирует темы, чтобы остановить спать или остановиться, как только они закончили обработку, на которых они работают. Это работает очень хорошо. Но часть, о которой я больше всего нервничает, проверяет, что все остановилось. Это то, что я делаю сейчас:

Int32 tries = 0;
while (tries < 5 && (Thread1Running || Thread2Running || Thread3Running))
{
    tries++;

    Thread.Sleep(TimeSpan.FromSeconds(5.0));
}

Основная причина, по которой мне не нравится, это то, что на основании на основе времени на базе времени, и если одна из моих потоков находится в середине длительной работы (что вполне вероятно), выключение может не закончить в этом 25 секунд (и это Очень важно, чтобы все эти темы были закрыты на время OnStop, где этот код запускается, отделка). Я не могу удалить попытки, потому что, если одна из тех нитей висит (они этого не делают, но вы никогда не знаете), то я действительно застрял, и сервис никогда не остановится.

Есть ли лучший способ сделать подтверждение того, что потоки все останавливаются, предпочтительно то, что это не на основе времени? Или я обречен, чтобы иметь какой-то тайм-аут, который может просто быть намного дольше (10 попыток с 30-дюймовым сон, может быть)?

Это было полезно?

Решение

Я считаю, что общий метод для этого должен присоединиться к потокам. Специфика вызова будет зависеть от библиотеки Threading, вы используете, но в целом join Метод будет блокировать до тех пор, пока нить не будет не доведена (и должна немедленно вернуться, если нить уже мертва). Таким образом, вы могли бы просто присоединиться к всем вашим потокам в последовательности, затем выйти. Если все ваши присоединения вернулись, то все темы вышли.

Многие резьбовые библиотеки позволяют добавить тайм-аут, чтобы присоединиться, что вы, вероятно, захотите сделать. Таким образом, даже если одна из ваших потоков зависает ваш код выхода не блокирует.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top