在C#中中止睡眠线程

时间:2014-01-06 15:01:22

标签: c# multithreading

我有一个独立的应用程序,可以创建许多线程,用于与我们的某个服务器执行各种事务。其中一个线程在给定的时间间隔内轮询服务器。我已经让Thread.Sleep(user_supplied_time_interval)使轮询线程在下一次轮询尝试之前等待给定的时间间隔。现在在关闭应用程序期间,我想要Abort()所有线程。为此,我将继续引用parentThread中的轮询线程并在pollerThread.Abort(); pollerThread.Join();中调用parentThread。但是我已经知道我无法中止睡眠线程。所以我在System.Threading.ThreadAbortException上获得了Thread.Sleep(user_supplied_time_interval)。 我显然可以设置一些布尔值来反映轮询器是要停止的,并在线程退出休眠状态后检查该布尔值。但是,如果轮询间隔很长,这也会延长应用程序退出,因为轮询器只有在退出休眠状态后才会返回。

这个问题的标准解决方案/方法是什么?或者我应该单独抓住System.Threading.ThreadAbortException并忽略它。

5 个答案:

答案 0 :(得分:2)

你应该不惜一切代价避免使用Thread.Abort,它可能导致各种奇怪的事情发生。

您可以使用ManualRestEvent代替,等待超时的事件与Sleep非常相似,您可以随时使用ManualRestEvent.Set唤醒。

你甚至可以为所有线程使用相同的事件,它也可以作为你的退出标志。

答案 1 :(得分:1)

计时器示例: 定时器每2秒运行一次

Timer t = new Timer(TimerCallback, null, 0, 2000);

private void TimerCallback(Object o) 
{
   //Run some code here   
}

答案 2 :(得分:0)

Thread.Abort不是一个好主意。

将您的主题设置为background

pollerThread.IsBackground = true;
  

后台线程与前台线程相同,除此之外   后台线程不会阻止进程终止。

答案 3 :(得分:0)

在管理线程的类中添加此属性。

    /// <summary>
    /// Used to tell the thread to exit.
    /// </summary>
    private readonly AutoResetEvent _eventDelay;

    /// <summary>
    /// True if the worker thread is running.
    /// </summary>
    private bool _isRunning;

在构造函数中初始化这样的事件。

        _eventDelay = new AutoResetEvent(false);

当你的工作线程需要休眠时,你可以暂停它的执行。

        _isRunning = true;
        while(_isRunning)
        {
            // do thread work stuff

            if(!_isRunning)
            {
                continue;
            }
            TimeSpan delay = // calculate how long the thread should sleep
            _eventDelay.WaitOne(delay);
        }

现在,您可以为您的工人类设置ShutDown方法。注意,在完成一次迭代工作之前,它不会停止线程。

    /// <summary>
    /// Flags the job to shutdown. It will stop execution
    /// as soon as possible.
    /// </summary>
    public void ShutDown()
    {
        if (!_isRunning)
        {
            return;
        }

        _isRunning = false;
        _eventDelay.Set();
    }

答案 4 :(得分:0)

我强烈建议您使用Reactive Extensions Framework(Rx)进行此类设置。根据间隔创建一个observable。当您不再需要轮询时,您可以处置订阅,框架将为您清理。

看一下这个例子,它可以帮助你:http://rxwiki.wikidot.com/101samples#toc28