【问题标题】:System.Threading.Timer stops the thread?System.Threading.Timer 停止线程?
【发布时间】:2014-11-14 08:55:42
【问题描述】:

计时器能否通过回调返回来停止正在运行的线程?

我需要一个计时器,它会在一定时间内运行某些功能。但是这个函数的持续时间超过了计时器滴答声。

_timer = new System.Threading.Timer(new TimerCallback(Process), null, TimeSpan.Zero, TimeSpan.FromHours(1));

和回调:

public void Process(Object stateinfo)
{
    DateTime dt = DateTime.Now.ToUniversalTime();
    //run once a day between 2 and 5 am
    if (LastCheckDateTime == DateTime.Today || dt.ToString("HHmm").CompareTo("0200") < 0 || dt.ToString("HHmm").CompareTo("0500") > 0)
    return;

    try
    {
       LastCheckDateTime = DateTime.Today;
       foo(); //lasts 4 hours
    }
    catch (Exception ex)
    {
       LastCheckDateTime = DateTime.MinValue;
       //if some problems, Process must start again until 5 am
    }
}

这段代码在今天凌晨 2 点 56 分开始但没有完成,这是因为早上 5 点它还在运行吗?

以及如何解决这个问题?

【问题讨论】:

  • 如果持续时间超过一个计时器,您想中止操作吗?
  • 不,没关系,我只是希望它从 2 点开始,如果出现问题则重新启动到 5 点。
  • “直到 5” 是什么意思?如果需要超过 3 小时,则重新启动它?
  • 为什么不只使用一个简单的机制,例如使用方法启动的时间填充会话变量,并在它停止时清除变量......然后在你的计时器中,如果会话变量被填充不要'不要运行超过 3 小时前停止它并重试...或类似的东西。
  • 不,如果超过 3 小时,我不想重新启动它,除非它捕获到异常。

标签: c# timer


【解决方案1】:

您的代码有效,您使用了我认为最好的计时器(System.Threading)。 即使之前的调用没有完成,重新执行相同的方法也没有问题。前一个实例没有被杀死。 您只需要管理重入,但您这样做的方式可以防止出现问题(您的计时器每小时触发一次,因此检查“LastCheckDateTime”的行和更改其值的行之间没有线程问题)。

我尝试了以下方法,效果很好:事件每秒触发一次,但“进程”从等待 3 秒开始。

 public partial class MainWindow : Window
{
    private System.Threading.Timer _timer;

    public MainWindow()
    {            
        InitializeComponent();
        _timer = new Timer(new System.Threading.TimerCallback(Process), null, TimeSpan.Zero, TimeSpan.FromSeconds(1));
    }

    private void Process(object state)
    {
        DateTime dt = DateTime.Now;
        System.Threading.Thread.Sleep(3000);
        Debug.WriteLine("dt=" + dt.ToString("HH:mm:ss.fff") + " Now=" + DateTime.Now.ToString("HH:mm:ss.fff"));

    }

}

最好的问候,

【讨论】:

  • 非常感谢您的回复,我只是想了解一下这个使用睡眠的好习惯吗?程序中还有另一个线程也使用 Sleeps,但它们是通过 Thread 实现的:new Thread(new ThreadStart(this.Process));
  • 我仍然不明白为什么 foo() 没有任何异常就停止了,有什么可以阻止它?计时器无法做到这一点?
  • 确实,你是对的,Thread.Sleep() 根本不是一个好习惯。但这对我来说真的很有用用于测试目的。对于“真实代码”,在我看来,总是可以使用计时器或异步代码(BackgroundWorker、事件、IAsyncResult、Task)来处理延迟。
猜你喜欢
  • 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
相关资源
最近更新 更多