简体   繁体   English

用于游戏开发的C#计时器

[英]C# Timers for game development

I want to find out the best way of creating time based events in games. 我想找出在游戏中创建基于时间的事件的最佳方法。 Lets talk for example about Texas Holdem Poker. 让我们谈谈德州扑克游戏。 Server can handle thousands of tables and in every table we have timers: turn timer, hold seat timer and so on. 服务器可以处理数千个表,并且每个表中都有计时器:转弯计时器,保持座位计时器等。

What is the best way of timers realization for this purpose? 为此目的实现计时器的最佳方法是什么?

Is System.Timers.Timer class can handle this or it will be more reasonable to create a separate thread with sorted time queue (for example an ascending sorted list with int values which represent time in ms remained)? 是System.Timers.Timer类可以处理此问题,还是创建一个具有排序时间队列的单独线程(例如,一个升序排序列表,其int值表示以毫秒为单位的时间)会更合理?

Thanks in advance, Valentin 预先感谢,瓦伦丁

I would suggest using System.Timers.Timer or System.Threading.Timer . 我建议使用System.Timers.TimerSystem.Threading.Timer Your idea of using a sorted queue is exactly how System.Threading.Timer is implemented, so you'd just be wasting your time and adding needless overhead. 您使用排序队列的想法正是System.Threading.Timer的实现方式,因此您将浪费时间并增加不必要的开销。 System.Timers.Timer is a wrapper around System.Threading.Timer . System.Timers.Timer是周围的包装System.Threading.Timer

I would not suggest using the current time (ie DateTime.Now or similar) to provide timeouts, because the clock can change at unpredictable times in unpredictable ways. 我不建议使用当前时间(即DateTime.Now或类似时间)来提供超时,因为时钟会以不可预测的方式在不可预测的时间改变。

If you want to base things on a "current time," then start a Stopwatch at the beginning of your program, and use the Elapsed property as the "current time" in the game. 如果要基于“当前时间”进行操作,则在程序开始时启动Stopwatch ,然后将Elapsed属性用作游戏中的“当前时间”。 So the time that's five seconds from the current time would be: 因此,距离当前时间五秒的时间是:

var FiveSecondsFromNow = GameTimer.Elapsed + TimeSpan.FromSeconds(5);

The question raised in comments is whether I would suggest using multiple timers with Elapsed events, or a list of actions that's maintained in time order and checked periodically (ie in a timer or in the main game loop). 评论中提出的问题是我是否建议使用带有Elapsed发生事件的多个计时器,还是按时间顺序维护并定期检查的动作列表(即在计时器或主游戏循环中)。

My immediate response would be to use a separate timer object for each event that needs to happen. 我的立即响应将是为需要发生的每个事件使用单独的计时器对象。 Doing so takes advantage of multiple cores when they're available (concurrent events can happen concurrently), and prevents me from having to maintain that list of pending actions. 这样做可以利用多个可用的内核(并发事件可以同时发生),并避免了我必须维护该未决操作列表。 I know that the timer queue implementation can handle thousands of individual timers without trouble, and it's almost certain that their implementation of the timer queue is going to be more efficient than mine. 我知道计时器队列的实现可以毫无问题地处理数千个计时器,而且几乎可以肯定的是,它们对计时器队列的实现将比我的效率更高。

Using timers simplifies the code, unless you have multithreading issues. 除非您有多线程问题,否则使用计时器可以简化代码。 And I'm all for simple. 我只是为了简单。 I'd only go to a manually maintained list of pending actions if I ran into performance problems with the timers. 如果我遇到计时器的性能问题,我只会进入手动维护的待处理操作列表。 And I'd be very sure that the timers were the culprit before I went to the effort of eliminating them. 在我努力消除计时器之前,我将非常确定计时器是罪魁祸首。

I often find not using timers at all the best approach. 我经常发现根本没有使用计时器是最好的方法。 Just store timestamps, and when you do processing, check the difference of the current time with the stored timestamp. 只需存储时间戳,然后在进行处理时,使用存储的时间戳检查当前时间的差值。

Minimize using threads when other easy solutions are available. 当有其他简单的解决方案可用时,尽量减少使用线程。

You should be able to 'process' all your tables often enough to handle all logic. 您应该能够足够经常地“处理”所有表以处理所有逻辑。 Unless we are talking really big numbers this shouldn't be a problem. 除非我们谈论的数字很大,否则这不是问题。

Unless you have some very heavy logic in your game which takes up a lot of processing, most likely not in texas hold'em, you shouldn't use threads, they only complicate things. 除非您的游戏中有非常繁琐的逻辑占用大量处理,而且很可能不在德州扑克中使用,否则您不应使用线程,它们只会使事情复杂化。 Why would you want to run something 'simultaneous' when it is perfectly possible to update the entire state of the games in one short update? 当完全有可能在一次简短的更新中更新整个游戏状态时,为什么要“同时”运行某些内容?

I would keep a sorted queue, but schedule a System.Timers.Timer to the time of the first event in the queue. 我将保留一个已排序的队列,但是将System.Timers.Timer调度到队列中第一个事件的时间。 When the event triggers I pick one element at a time from the queue, process the element, peak at the next to see if the time has passed. 当事件触发时,我一次从队列中选择一个元素,处理该元素,在下一个达到峰值,以查看时间是否过去。 If the time has passed, process the event, otherwise schedule a timer for the remaining time. 如果时间已过去,请处理事件,否则请为剩余时间安排一个计时器。

When new event arrive you insert them in the sorted queue. 当新事件到达时,将它们插入已排序的队列中。 If they happens to be first in the queue, reset the timer and restart it with the interval to the new first element. 如果它们恰好在队列中的第一位,请重置计时器,并以一定间隔将其重新启动到新的第一个元素。

This all assumes you need to trigger something to happen. 所有这些都假定您需要触发某些事情。 If you just want to know when someone asks if there is a new event you don't need no timers, nor extra threads to handle the queue. 如果您只是想知道何时有人问是否有新事件,则不需要计时器,也不需要额外的线程来处理队列。 Just check your event queue when someone asks. 有人问时,只需检查您的事件队列即可。

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

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