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

问题描述 投票:0回答:1

我用 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();
});
c# timer scheduled-tasks scheduler
1个回答
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();

© www.soinside.com 2019 - 2024. All rights reserved.