簡體   English   中英

在運行時更改計時器 c#

[英]Change timer at runtime c#

我使用調度程序時間創建了一個計時器:

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

我用它來達到 object 的速度。每個滴答聲對象移動 10 個像素。 我想知道如何提高 object 的速度而不改變它每次滴答移動的像素,這意味着我想在運行期間每 10 秒左右使計時器本身更快。 有什么辦法可以做到嗎?我試過做一個可變速度=0,每次我數到10然后增加它

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

但是 object 保持相同的速度。所以我是否必須制作自己的計時器 class 而不是使用內置的調度程序時間,如果是這樣我該怎么做?或者是否有其他解決方案?

我認為DispatcherTimer並不是您執行此任務的最佳盟友。 該類絕不是旨在以精確的間隔執行操作。

我會試着更好地解釋一下:即使DispatcherTimer ,顧名思義,調度行動及時,具有很高的精度,派出行動將進行排隊,然后在執行時的基本GUI線程決定對其進行處理。

通常, GUI線程的分辨率大約為8ms (這是一個近似值,但我認為我們現在不需要測量此值)...並且您使用的是80ms的起始Interval ,隨着時間的流逝, Interval會逐漸減小它可能超過了8ms左右的容限。 同時,您還將一遍又一遍地重繪界面(或界面的一部分),這會進一步影響GUI的性能和響應速度:如果GUI線程正忙於重繪,並且需要的Interval值不止完成后,僅當GUI線程完成正在進行的任務時,才會處理下一個調度的動作。

如果需要更精確的調度,以避免掛起/失去響應能力/延遲動作,則需要使用在后台運行的計時器類,例如System.Threading.Timer (對SyncronizationContext來說是Google,對您有所幫助)或System.Timers.Timer

最重要的是,顯示速度變化時切勿間隔播放。 以固定的間隔工作,並以像素為單位增加/減少移動的“大小”。 您應該能夠毫無問題地計算出增量。 只是為了使事情更清楚: 如果我想放慢一個對象的速度加倍,我不會將繪制該對象的計時器間隔減半,但是我會將對象在每一步所經過的像素數量加倍

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 你不能看看這個存儲庫; [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