2011-11-29 96 views
6

我有一个应用程序使用定时器偶尔在辅助线程上运行监视任务。其中一些清理任务需要很长时间,我希望能够在用户结束程序时中止这些任务(如果可能,请优雅地)。我可以停止System.Threading.Timer

有没有什么办法可以通过编程方式中止线程,就像我可以使用Thread.Abort()一样,还是必须向代码中添加一个标志来指示线程已经完成,并检查该线程中的valrious地方由定时器启动的代码?

+0

终止该应用程序将终止所有线程? – CJ7

回答

4

没有办法知道Thread,其中Threading.Timer回调将提前运行。因此没有通用的方法来中止它。有可能使回调本身与Thread实例通信,但它会打开一些竞争条件

注意:一般情况下,使用Abort是一种不好的做法。这是一种相当可靠的方式,最终难以发现死锁和/或资源泄漏。使用被动机制如CancellationToken

+0

再一次,中止弊端+1。 –

5

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

作为一个方面说明,除非你绝对100%确定你知道它将被留下的状态,否则你不应该使用thread.abort()。它会以奇怪的方式严重地破坏你的应用程序的稳定性。

+0

+1避免像瘟疫一样的Thread.Abort()...他们甚至不允许TPL中的Abort()。 –

1

你的意思是沿着这些线?

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 ; 
    } 

} 
3

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

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

0
public void stopTimer(){ 
    myThreadingTimer = null; 
} 

解释:销毁对象=销毁进程。

+0

通常情况下,如果答案包含对代码意图做什么的解释,以及为什么解决问题而不介绍其他问题,答案会更有帮助。 (这篇文章被至少一个用户标记,大概是因为他们认为没有解释的答案应该被删除。) –

+0

解释:销毁对象=销毁进程。 –

相关问题