5/4/2023 0 Comments Rune 2 timer![]() Well, they do now! I made a similar post in the Runes Guide sub forum. Instead, you'll have a pool of timers (much like the Thread Pool, no?).According to the excellent Runes Guide put together by kakola and mortivore and published in this forum, they don't know anyone who has gotten a 5* rune with glory points. That'll prevent you from leaking one timer for every event. You can grow the queue dynamically if you have to, and you could even groom it from time to time. When the timeout expires, you clear the timer and put it back on the queue. When you need a timer, you pull one from the queue, set it, and add it to your collection. their timeout and intervals set to Timeout.Infinite). As long as you don't have thousands of these things sitting around un-disposed for a long period, it's not going to be a problem.Īnother option is to have a queue of timers that remains allocated, but deactivated (i.e. You're just leaking a handle for a brief period. With no references to the object, it will be eligible for garbage collection, meaning that the Dispose method will be called by the finalizer. You can just remove the timer from the collection and not dispose it. But it's kind of a wonky thing to do, I'll admit. I seem to recall doing this in the past, and it worked okay. You could have a single thread and a priority queue of actions keyed on time, but that's needless complexity.Ĭalling Dispose in the callback probably isn't a good idea, although I'd be tempted to give it a try. You certainly don't want to create a new thread for every one of them. ![]() The model you have, using a one-shot timer, is definitely the way to go. It can be called as follows - and is very lightweight: var scheduler = new Scheduler() _scheduledTasks.TryRemove(task.Action, out deleted) Private void RemoveTask(object sender, EventArgs e) Var task = new ScheduledTask(action, timeoutMs) Public void Execute(Action action, int timeoutMs) Private readonly ConcurrentDictionary _scheduledTasks = new ConcurrentDictionary() Then, create a scheduler class - again, very simple: class Scheduler Private void TimerElapsed(object sender, e) Public ScheduledTask(Action action, int timeoutMs) The lightest weight solution is to use a timer - particularly if you will have many tasks to throw at it.įirst make a simple scheduled task class: class ScheduledTask Thread.Sleep or even AutoResetEvent.WaitOne(timeout) are not good - they will tie up thread pool resources, I have been burned trying this! The "fire once with a delay" seems like such a common problem that there should be an easy way to do this, probably some other library in System.Threading I am missing, but right now the only solution I can think of is modification of the above with a dedicated cleanup task running on an interval. Timers are considered live while their lambdas are executing, but even if this is the case I'd rather dispose it properly. I am unsure if it is safe to "fall off" the end, i.e. The problem is that calling Dispose() from the callback itself cannot be good. }, currentKey, Timeout.Infinite, Timeout.Infinite If(timers.TryRemove((long)key, out lTimer)) Long currentKey = Interlocked.Increment(ref currentKey) Protected void Execute(Action action, int timeout_ms) So far, the best I can do is this: long currentKey = 0 ĬoncurrentDictionary timers = new ConcurrentDictionary() I also really, really want to avoid Thread.Sleep(). I am trying to create a function that takes in an Action and a Timeout, and executes the Action after the Timeout.
0 Comments
Leave a Reply. |