如何停止 System.Threading.Timer,然后更改其参数并再次运行? [复制]

Posted

技术标签:

【中文标题】如何停止 System.Threading.Timer,然后更改其参数并再次运行? [复制]【英文标题】:How to stop a System.Threading.Timer, then change its parameters and run it again? [duplicate] 【发布时间】:2021-09-10 16:35:15 【问题描述】:

我用 C# 创建了一个计时器。我可以在几秒钟、几分钟或每天安排任何操作。 但是,在某些情况下,我想停止此计时器,然后更改其参数并再次运行它(例如单击按钮时)。我该怎么做?

以下是我写的代码。

SchedulerService.cs

public class SchedulerService

    private static SchedulerService _instance;
    private List<Timer> timers = new List<Timer>();
    private SchedulerService()  
    public static SchedulerService Instance => _instance ?? (_instance = new SchedulerService());
    public void ScheduleTask(int hour, int min, double intervalInHour, Action task)
    
        DateTime now = DateTime.Now;
        DateTime firstRun = new DateTime(now.Year, now.Month, now.Day, hour, min, 0, 0);
        if (now > firstRun)
        
            firstRun = firstRun.AddDays(1);
        
        TimeSpan timeToGo = firstRun - now;
        if (timeToGo <= TimeSpan.Zero)
        
            timeToGo = TimeSpan.Zero;
        
        var timer = new Timer(x =>
        
            task.Invoke();
        , null, timeToGo, TimeSpan.FromHours(intervalInHour));
        timers.Add(timer);
    

Scheduler.cs(根目录下的文件)

public class Scheduler
    
        public static void IntervalInSeconds(int hour, int sec, double interval, Action task)
        
            interval = interval / 3600;
            SchedulerService.Instance.ScheduleTask(hour, sec, interval, task);
        
        public static void IntervalInMinutes(int hour, int min, double interval, Action task)
        
            interval = interval / 60;
            SchedulerService.Instance.ScheduleTask(hour, min, interval, task);
        
        public static void IntervalInHours(int hour, int min, double interval, Action task)
        
            SchedulerService.Instance.ScheduleTask(hour, min, interval, task);
        
        public static void IntervalInDays(int hour, int min, double interval, Action task)
        
            interval = interval * 24;
            SchedulerService.Instance.ScheduleTask(hour, min, interval, task);
        

    

Form1.cs

Scheduler.IntervalInMinutes(hour,minute,interval,
() =>

 MyFunc();
);

【问题讨论】:

这有用吗? Reliably stop System.Threading.Timer? 嗨,我用它来使它尽可能短。这有帮助。谢谢 【参考方案1】:

我不会重新发明***。 Microsoft 已经有一个库可以很好地为您做到这一点。您应该使用 Microsoft 的反应式框架(又名 Rx) - NuGet System.Reactive 并添加 using System.Reactive.Linq;

你可以这样做:

IDisposable subscription =
    Observable
        .Interval(TimeSpan.FromSeconds(1.0))
        .Subscribe(x => Console.WriteLine(x));

这将每秒触发一个事件。如果您想停止它,只需致电subscription.Dispose();

如果您想要一个不同的时间段,请输入 TimeSpan.FromDays(2.0) 之类的内容。

现在,如果您希望能够更改周期,您可以这样做:

Subject<TimeSpan> subject = new Subject<TimeSpan>();

IObservable<long> interval =
    subject
        .Select(timespan => Observable.Interval(timespan))
        .Switch();

IDisposable subscription =
    interval
        .Subscribe(x => Console.WriteLine(x));

现在,要开始间隔,我会这样称呼:

subject.OnNext(TimeSpan.FromSeconds(1.0));

如果我现在想更改它,我只需这样做:

subject.OnNext(TimeSpan.FromHours(2.0));

再一次,要停止它,只需调用subscription.Dispose();

【讨论】:

我不知道,谢谢。

以上是关于如何停止 System.Threading.Timer,然后更改其参数并再次运行? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

Tomcat停止时如何停止执行线程?

Android如何停止线程的方式

如何将VBS停止

如何停止Discovery Studio 2.5任务(job)

如何彻底停止job

按下“停止”按钮时如何停止动画并冻结图像