如何停止 System.Threading.Timer,然后更改其参数并再次 运行?
How to stop a System.Threading.Timer, then change its parameters and run it again?
我用 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();
});
我不会重新发明轮子。 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();
。
我用 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();
});
我不会重新发明轮子。 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();
。