C # убивает поток - PullRequest
       8

C # убивает поток

4 голосов
/ 22 июля 2010

В моем приложении есть поток, который работает непрерывно.Используя Thread.Sleep (), функция выполняется каждые 10 минут.

Мне нужно иметь возможность убить этот поток, когда пользователь нажимает кнопку.Я знаю, что Thread.Abort () не является надежным.Я могу использовать переменную, чтобы остановить поток, но поскольку он спит, может пройти еще 10 минут, прежде чем поток убьет себя.

Есть идеи?

Ответы [ 5 ]

9 голосов
/ 22 июля 2010

Почему бы вам не использовать таймер для планирования задачи каждые десять минут.Это запустит ваш код в потоке пула потоков, и вам не придется управлять этим самостоятельно.

Подробнее см. System.Threading.Timer class.

4 голосов
/ 22 июля 2010

Итак, вот пример, по которому пользователи могут выполнять работу по совету Брайана. Используйте старт / стоп по мере необходимости. Чтобы очистить объект (Program), как только вы закончите, обязательно вызовите Dispose.

Просто обратите внимание, что когда вы вызываете Stop, он не позволяет снова запускать таймер, однако у вас все еще может быть рабочий поток в середине выполнения обработчика timer_Elapsed, то есть остановка таймера не останавливает выполняемый в данный момент рабочий поток.

using System;
using System.Timers;

namespace TimerApp
{
    class Program : IDisposable
    {
        private Timer timer;

        public Program()
        {
            this.timer = new Timer();
            this.timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
            this.timer.AutoReset = true;
            this.timer.Interval = TimeSpan.FromMinutes(10).TotalMilliseconds;
        }

        void timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            // TODO...your periodic processing, executed in a worker thread.
        }

        static void Main(string[] args)
        {
            // TODO...your app logic.
        }

        public void Start()
        {
            this.timer.Start();
        }

        public void Stop()
        {
            this.timer.Stop();
        }

        public void Dispose()
        {
            this.timer.Dispose();
        }
    }
}
4 голосов
/ 22 июля 2010

Вместо Thread.Sleep используйте System.Threading.ManualResetEvent.У метода WaitOne есть тайм-аут, аналогичный Thread.Sleep, ваш поток будет находиться в спящем режиме в течение этого интервала, если только событие не инициировано первым, а возвращаемое значение указывает, истек ли интервал или было установлено событие.

3 голосов
/ 22 июля 2010

Опираясь на ответ Бена, вот пример, который вам поможет ...

using System.Threading;

public class MyWorker {
        private ManualResetEvent mResetEvent = new ManualResetEvent(false);
        private volatile bool mIsAlive;
        private const int mTimeout = 6000000;

        public void Start()
        {
            if (mIsAlive == false)
            {
                mIsAlive = true;
                Thread thread = new Thread(new ThreadStart(RunThread));
                thread.Start();
            }
        }

        public void Stop()
        {
            mIsAlive = false;
            mResetEvent.Set();
        }

        public void RunThread()
        {
            while(mIsAlive)
            {
                //Reset the event -we may be restarting the thread.
                mResetEvent.Reset();

                DoWork();

                //The thread will block on this until either the timeout
                //expires or the reset event is signaled.
                if (mResetEvent.WaitOne(mTimeout))
                {
                    mIsAlive = false; // Exit the loop.
                }
            }
        }

        public void DoWork()
        {
            //...
        } }
2 голосов
/ 22 июля 2010

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

В стороне: Это не обязательно решение best , но оно, вероятно, самое быстрое в реализации,Как и для всех других возможностей, вам следует провести анализ затрат и выгод при выборе того, какое решение вам подходит.

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

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

...