简体   繁体   English

在运行时更改计时器 c#

[英]Change timer at runtime c#

Iv'e created a timer using dispatcher time:我使用调度程序时间创建了一个计时器:

time = new DispatcherTimer();
time.Interval = new TimeSpan(0, 0, 0, 0, 80);

and I use it for the speed of an object.Each tick the objects moves 10 pixels.我用它来达到 object 的速度。每个滴答声对象移动 10 个像素。 I would like to know how to increase the speed of the object without changing the pixels it moves each tick, meaning I want to make the timer itself faster during run time every 10 seconds or so.我想知道如何提高 object 的速度而不改变它每次滴答移动的像素,这意味着我想在运行期间每 10 秒左右使计时器本身更快。 Is there a way I can do it?Ive tried making a variable speed=0 and increasing it each time I count 10 and then有什么办法可以做到吗?我试过做一个可变速度=0,每次我数到10然后增加它

time.Interval = new TimeSpan(0, 0, 0, 0, 80-speed); 

but The object stayed in the same speed.So do I have to make my own timer class instead of using the built in dispatcher time, if so how do I do that?or is there another solution for this?但是 object 保持相同的速度。所以我是否必须制作自己的计时器 class 而不是使用内置的调度程序时间,如果是这样我该怎么做?或者是否有其他解决方案?

I think that DispatcherTimer is not your best ally for this task. 我认为DispatcherTimer并不是您执行此任务的最佳盟友。 The class is by no means designed to execute actions at precise intervals. 该类绝不是旨在以精确的间隔执行操作。

I'll try to better explain myself: even if the DispatcherTimer , as its name suggests, dispatches actions timely and with a great precision, the dispatched actions will be queued and then executed when the underlying GUI thread decides to process them. 我会试着更好地解释一下:即使DispatcherTimer ,顾名思义,调度行动及时,具有很高的精度,派出行动将进行排队,然后在执行时的基本GUI线程决定对其进行处理。

Normally, a GUI thread has a resolution of around 8ms (it's an approximation, but I don't think we need to measure this right now)... and you are using a starting Interval of 80ms that is going to decrease over time until it probably goes beyond that tolerance limit of 8ms or so. 通常, GUI线程的分辨率大约为8ms (这是一个近似值,但我认为我们现在不需要测量此值)...并且您使用的是80ms的起始Interval ,随着时间的流逝, Interval会逐渐减小它可能超过了8ms左右的容限。 In the meanwhile, you are also repainting your interface (or part of it) over and over and this impacts the performance and the responsiveness of the GUI even more: if the GUI thread is busy repainting and that requires more than the Interval value to be accomplished, the next dispatched action will be processed only once the GUI thread completes the undergoing task. 同时,您还将一遍又一遍地重绘界面(或界面的一部分),这会进一步影响GUI的性能和响应速度:如果GUI线程正忙于重绘,并且需要的Interval值不止完成后,仅当GUI线程完成正在进行的任务时,才会处理下一个调度的动作。

If you need a more precise scheduling, avoiding hangings / losses of responsiveness / delayed actions, you need to use a timer class that runs in background like System.Threading.Timer (google for SyncronizationContext , that would be helpful) or System.Timers.Timer . 如果需要更精确的调度,以避免挂起/失去响应能力/延迟动作,则需要使用在后台运行的计时器类,例如System.Threading.Timer (对SyncronizationContext来说是Google,对您有所帮助)或System.Timers.Timer

On the top of that, never play with intervals when showing a change in speed. 最重要的是,显示速度变化时切勿间隔播放。 Work with a fixed interval and increase/decrease the movement "size" in pixels. 以固定的间隔工作,并以像素为单位增加/减少移动的“大小”。 You should be able to calculate the delta without problems. 您应该能够毫无问题地计算出增量。 Just to make things clearer: if I want to slow that the speed of an object doubled, I don't half the timer interval that draws the object, but I double the amount of pixels my object traverses at each step . 只是为了使事情更清楚: 如果我想放慢一个对象的速度加倍,我不会将绘制该对象的计时器间隔减半,但是我会将对象在每一步所经过的像素数量加倍

using System;
using System.Collections.Generic;
using System.Linq;

namespace CQRS_and_EventSourcing
{
    internal class Program
    {
        //CQRS = command query responsibility segregation
        //CQS= command query separation

        //COMMAND

        public class PersonStroge
        {
            Dictionary<int, Person> people;
        }

        public class Person
        {
            public int UniqueId;
            public int age;
            EventBroker broker;

            public Person(EventBroker broker)
            {
                this.broker = broker;
                broker.Commands += BrokerOnCommands;
                broker.Queries += BrokeronQueries;
            }

            private void BrokeronQueries(object sender, Query query)
            {
                var ac = query as AgeQuery;
                if (ac != null && ac.Target == this)
                {
                    ac.Result = age;
                }
            }

            private void BrokerOnCommands(object sender, Command command)
            {
                var cac = command as ChangeAgeCommand;
                if (cac != null && cac.Target == this)
                {
                    if (cac.Register)
                        broker.AllEvents.Add(new AgeChangedEvent(this, age, cac.Age));
                    age = cac.Age;
                }
            }
            public bool CanVote => age >= 16;
        }
        public class EventBroker
        {
            //1. All events that happened.
            public IList<Event> AllEvents = new List<Event>();
            //2. Commands
            public event EventHandler<Command> Commands;
            //3. Query
            public event EventHandler<Query> Queries;

            public void Command(Command c)
            {
                Commands?.Invoke(this, c);
            }

            public T Query<T>(Query q)
            {
                Queries?.Invoke(this, q);
                return (T)q.Result;
            }

            public void UndoLast()
            {
                var e = AllEvents.LastOrDefault();
                var ac = e as AgeChangedEvent;
                if (ac != null)
                {
                    Command(new ChangeAgeCommand(ac.Target, ac.OldValue) { Register = false });
                    AllEvents.Remove(e);
                }
            }
        }
        public class Query
        {
            public object Result;
        }
        public class AgeQuery : Query
        {
            public Person Target;
        }
        public class Command : EventArgs
        {
            public bool Register = true;
        }
        public class ChangeAgeCommand : Command
        {
            public Person Target;
            //public int TargetId;
            public int Age;

            public ChangeAgeCommand(Person target, int age)
            {
                Target = target;
                Age = age;
            }
        }

        public class Event
        {
            //backtrack
        }
        public class AgeChangedEvent : Event
        {
            public Person Target;
            public int OldValue, NewValue;

            public AgeChangedEvent(Person target, int oldValue, int newValue)
            {
                Target = target;
                OldValue = oldValue;
                NewValue = newValue;
            }
            public override string ToString()
            {
                return $"Age changed from {OldValue} to {NewValue}";
            }
        }

        static void Main(string[] args)
        {
            var eb = new EventBroker();
            var p = new Person(eb);

            eb.Command(new ChangeAgeCommand(p, 123));

            foreach (var e in eb.AllEvents)
            {
                Console.WriteLine(e);
            }
            //int age;

            //age = eb.Query<int>(new AgeQuery { Target = p });
            //Console.WriteLine(age);

            //eb.UndoLast();
            //foreach (var e in eb.AllEvents)
            //{
            //    Console.WriteLine(e);
            //}

            //age = eb.Query<int>(new AgeQuery { Target = p });
            //Console.WriteLine(age);

            Console.ReadKey();
        }
    }
}

İf you couldnt make look at this repository; İf 你不能看看这个存储库; [1]: https://github.com/kYasinAblay/DNesteruk.Additional.Lectures/blob/master/CQRS_and_EventSourcing/Program.cs [1]: https://github.com/kYasinAblay/DNesteruk.Additional.Lectures/blob/master/CQRS_and_EventSourcing/Program.cs

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM