从不同的计时器 C# 切换

本文关键字:切换 计时器 | 更新日期: 2023-09-27 18:35:17

我正在创建一个 Windowns 手机 8 应用程序(c#),它是一个倒数间隔计时器,所以有准备时间(10 秒)、工作时间(20 秒)、休息时间(10 秒)。我有这些变量

  `TimeSpan prepInterval = new TimeSpan(0, 0, 0, 10);
   TimeSpan workInterval = new TimeSpan(0, 0, 0, 20);
   TimeSpan restInterval = new TimeSpan(0, 0, 0, 10);`

我无法想象让他们在他们达到 0 时一个接一个地实现它们。因此,当准备时间完成后,工作计时器将启动,当它被确定时,其余计时器将启动。

从不同的计时器 C# 切换

如果你想在所有这些中有更多的分解逻辑,也许你可以基于一个简单的接口创建一些类,如下所示:

interface ITimerAction
{
    int Seconds { get; set; }
    bool Started { get; }
    bool Completed { get; }
    void OnStart();
    void OnComplete();
}
interface ITimerActionList
{
    void Add(ITimerAction action);
    void Work();
    event EventHandler OnCompletedEvent;
}

然后,这将允许您创建一个抽象的TimerAction类,并且TimerActionList

abstract class TimerAction : ITimerAction
{
    public virtual int Seconds
    {
        get;
        set; 
    }
    public virtual bool Completed
    {
        get;
        protected set;
    }
    public virtual bool Started
    {
        get;
        protected set; 
    }
    public abstract void OnStart();
    public abstract void OnComplete();
}
class TimerActionList : ITimerActionList
{
    public event EventHandler OnCompletedEvent;
    private readonly IList<ITimerAction> actions = new List<ITimerAction>();
    private bool working = false;
    private Thread myThread;
    public void Add(ITimerAction action)
    {
        if (working)
        {
            throw new InvalidOperationException("Cannot add new timers when work is already in progress");
        }
        actions.Add(action);
    }
    protected virtual void DoWork()
    {
        working = true;
        int currentStep = 0, maxSteps = actions.Count;
        while (currentStep < maxSteps)
        {
            ITimerAction action = actions[currentStep];
            if (!action.Started)
            {
                action.OnStart();
            }
            if (action.Completed)
            {
                currentStep++;
                continue;
            }
            if (action.Seconds == 0)
            {
                action.OnComplete();
                continue;
            }
            action.Seconds--;
            Thread.Sleep(1000);
        }
        Completed();
    }
    public void Work()
    {
        if (working)
        {
            throw new InvalidOperationException("Already running!");
        }
        working = true;
        myThread = new Thread(DoWork);
        myThread.Start();
    }
    protected virtual void Completed()
    {
        myThread = null;
        working = false;
        actions.Clear();
        var local = OnCompletedEvent;
        if (local != null)
        {
            local.Invoke(this, EventArgs.Empty);
        }
    }
}

然后,您可以编写从 TimerAction 类继承的类,这些类可以处理计时器运行之前和之后的操作:)

class PrepareTimer : TimerAction
{
    public override void OnStart()
    {
        Console.WriteLine("Preparing");
        Started = true;
    }
    public override void OnComplete()
    {
        Console.WriteLine("Prepare ready");
        Completed = true;
    }
}
class WorkTimer : TimerAction
{
    public override void OnStart()
    {
        Console.WriteLine("Working");
        Started = true;
    }
    public override void OnComplete()
    {
        Console.WriteLine("Work ready");
        Completed = true;
    }
}
class CoolDownTimer : TimerAction
{
    public override void OnStart()
    {
        Console.WriteLine("Cooling down");
        Started = true;
    }
    public override void OnComplete()
    {
        Console.WriteLine("Cooldown ready");
        Completed = true;
    }
}

然后你可以这样测试代码

static void Main(string[] args)
{
    bool done = false;
    ITimerActionList mylist = new TimerActionList();
    mylist.Add(new PrepareTimer { Seconds = 1 });
    mylist.Add(new WorkTimer { Seconds = 2 });
    mylist.Add(new CoolDownTimer { Seconds = 1 });
    mylist.OnCompletedEvent += (sender, e) =>
    {
        done = true;
    };
    mylist.Work();
    while (!done)
    {
        // timer is running
    }
    Console.WriteLine("Done!");
}

(控制台程序,但我想这也要演示?

下面是一个基于deathismyfriend和Hans Passant建议的例子:

var start = new DateTime();
var stage = 0;
var timer = new System.Timers.Timer(100);
timer.Elapsed += (s, e) =>
{
    var elapsed = DateTime.Now - start;
    int duration = stage == 1 ? 20 : 10;
    if (elapsed.TotalSeconds > duration)
    {
        start = DateTime.Now;
        stage++;
        if (stage > 2)
            timer.Stop();
    }
};
start = DateTime.Now;
stage = 0;
timer.Start();