【问题标题】:Can I stop a System.Threading.Timer我可以停止 System.Threading.Timer
【发布时间】:2011-11-29 19:11:49
【问题描述】:

我有一个应用程序,它使用计时器偶尔在辅助线程上运行监视任务。其中一些清理任务需要花费大量时间,我希望能够在我的用户结束程序时中止这些任务(如果可能的话,优雅地)。

有没有办法像使用 Thread.Abort() 一样以编程方式中止线程,或者我必须在代码中添加一个标志以指示线程已完成并在代码中的 valrious 位置检查它是由定时器启动的?

【问题讨论】:

标签: c# multithreading timer


【解决方案1】:

您可以使用.change 在回调执行之前停止计时器,但是一旦回调开始执行,您应该使用应用程序级别的标志来允许您的代码退出。

附带说明,除非您绝对 100% 确定您知道它将处于的状态,否则您不应使用 thread.abort()。它会以奇怪的方式严重破坏您的应用程序的稳定性。

【讨论】:

  • +1 避免 Thread.Abort() 像瘟疫一样......他们甚至不允许在 TPL 中使用 Abort()。
【解决方案2】:

无法提前知道Threading.Timer 回调将在哪个Thread 上运行。因此,没有通用的方法来中止它。可以让回调本身与 Thread 实例进行通信,但它会打开几个竞争条件

注意:通常使用Abort 是一种不好的做法。这是一种相当可靠的方法,最终很难检测到死锁和/或资源泄漏。最好使用像CancellationToken这样的被动机制

【讨论】:

  • 再次,关于堕胎的弊端 +1。
【解决方案3】:

使用 this.Timer.Change(Timeout.Infinite, Timeout.Infinite); 首先我使用了 .dispose 方法,但在我的情况下它不起作用,所以我使用了 Timer.change。

这是我找到的最佳解决方案。

【讨论】:

    【解决方案4】:

    你的意思是这样的?

    using System;
    using System.Threading ;
    
    class AppCore : IDisposable
    {
        Timer    TimerInstance ;
        string[] Args          ;
    
        public AppCore( string[] args )
        {
            if ( args == null ) throw new ArgumentNullException("args") ;
            this.TimerInstance   = new Timer( Tick , null , new TimeSpan(0,0,30) , new TimeSpan(0,0,15) ) ;
            this.Args            = args ;
            this.Cancelled       = false ;
            this.Disposed        = false ;
            return ;
        }
    
        public int Run()
        {
            // do something useful
            return 0 ;
        }
    
        private bool Cancelled ;
        public void Cancel()
        {
            lock( TimerInstance )
            {
                Cancelled = true ;
                TimerInstance.Change( System.Threading.Timeout.Infinite , System.Threading.Timeout.Infinite ) ;
            }
            return ;
        }
    
        private void Tick( object state )
        {
            if ( !Cancelled )
            {
                // do something on each tick
            }
            return ;
        }
    
        private bool Disposed ;
        public void Dispose()
        {
            lock ( TimerInstance )
            {
                if ( !Disposed )
                {
                    using ( WaitHandle handle = new EventWaitHandle( false , EventResetMode.ManualReset ) )
                    {
                        TimerInstance.Dispose( handle ) ;
                        handle.WaitOne() ;
                    }
                    Disposed = true ;
                }
            }
            return ;
        }
    
    }
    

    【讨论】:

      【解决方案5】:
      public void stopTimer(){
          myThreadingTimer = null;
      }
      

      说明:销毁对象 = 销毁进程。

      【讨论】:

      • 一般来说,如果答案包含对代码的用途的解释,以及为什么在不介绍其他人的情况下解决问题的原因,答案会更有帮助。 (该帖子至少被一位用户标记,大概是因为他们认为应该删除没有解释的答案。)
      • 说明:销毁对象=销毁进程。
      • 运行计时器不会被垃圾回收stackoverflow.com/questions/18136735/…
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多