如何解决如何停止 System.Threading.Timer,然后更改其参数并再次运行它?
我用 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);
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,Action task)
{
interval = interval / 60;
SchedulerService.Instance.ScheduleTask(hour,task);
}
public static void IntervalInHours(int hour,Action task)
{
SchedulerService.Instance.ScheduleTask(hour,task);
}
public static void IntervalInDays(int hour,Action task)
{
interval = interval * 24;
SchedulerService.Instance.ScheduleTask(hour,task);
}
}
Form1.cs
Scheduler.IntervalInMinutes(hour,minute,() =>
{
MyFunc();
});
解决方法
我不会重新发明轮子。 Microsoft 已经有一个库可以很好地为您执行此操作。您应该使用 Microsoft 的 Reactive Framework(又名 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();
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。