[英]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.