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 c开发者_Python百科reate a separate thread with sorted time queue (for example an ascending sorted list with int values which represent time in ms remained)?
Thanks in advance, Valentin
I would suggest using System.Timers.Timer
or System.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.Timers.Timer
is a wrapper around System.Threading.Timer
.
I would not suggest using the current time (i.e. DateTime.Now
or similar) to provide timeouts, because the clock can change at unpredictable times in unpredictable ways.
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. 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 (i.e. in a timer or in the main game loop).
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. 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.
精彩评论