Remove and reset Static Object - c#

I am working on an app that has a static countdown running. It needs to be static since the object itself needs to be accessed from different classes.
But after redoing this bit of code for a while:
timer.Stop();
timer.Dispose();
timer.Enabled = false;
timer = new System.Timers.Timer();
timer.Interval = 10;
timer.Elapsed += OnTimedEvent;
timer.Enabled = true;
My app becomes extremely slow. I believe that maybe I am not disposing the timer object right and therefore creating many objects in the ram. Evneutally, after many times of this code, the app fails.
Am I disposing the object right before setting it up again (with the new keyword)? Or am I missing something vital?
Thank you!
It is:
public static System.Timers.Timer timer;
Well the reason why this is static, is because in my activity in my app there is also a recyler view integrated. And when I click on an item in my recycler view i need to manipulate the timer from outside the recycler view but inside the activity as well. If the timer is not public static I would have to intstantiate another object of that timer but this is not affecting the currently running timer. So maybe I got this all wrong? Is there a third option? Thank you!

In these kinds of scenarios, your best bet is to reuse the existing timer rather than dispose old ones and create new ones. This saves you having to worry about unsubscribing event handlers etc.
I suspect you want to Stop and Start it instead.

Related

How to keep reusing timer

I'm making a simple game on console for practice that requires a time limit each round and I've encountered a problem with trying to make it so I can use timer more than once. I have this:
class Program
{
static Timer timer = new Timer(1000);
static int t = 10;
static void Main(string[] args)
{
timer.Elapsed += Timer_Elapsed1;
timer.Start();
Console.ReadLine();
t = 10;
timer.Start();
Console.ReadLine();
}
My thoughts were that the 2nd timer.Start() would get the same result as the first, but nothing happens.
private static void Timer_Elapsed1(object sender, ElapsedEventArgs e)
{
t--;
Console.WriteLine("Hello!");
if (t == 0)
{
Console.WriteLine("Goodbye!");
timer.Stop();
}
}
Why is the second timer.Start() not doing anything? How do I make it so I can use timer.Start() again and it will do the same thing as the first time? I'm using System.Timers
NVM IT DOES WORK, IM JUST DUMB LOL
Try stopping or disabling the first timer before trying to start a second time.
C# - how do you stop a timer?
I fell compelled to give you some disclaimers:
First, console is not the right Environment for Game Development. Neither is any of the GUI techs. For games you got XNA (pretty dated) and with .NET Core a bunch of new Options. The important thing is that you have a Game Loop of some form. Or at least imitate one.
Secondly, I am unsure how well most Timers work in console apps. Most of them use callbacks wich usually require a MessageQueue - wich is a GUI feature. I guess you could try a Multithreading time, but then you have to relearn everything if you leave Console applications.
As for your code: I am unsure when the Timer tick happens since you specified no interval. But I guess either:
never
after the 2nd timer start

C# System.Timers.Timer - Please, how do I make it stop?

I've got a Timer that's doing a 60 second countdown. When the ticks hit 60 seconds, it stops and disposes - no problem (I think). This is run in the context of a WebApi service. I need to be able to cancel the countdown from a UI, so I've exposed a method to handle this. Since the controller is transient (thanks Luaan) and, as Daniel points out, the app pool is not predictable, I need a way to send a "cancellable" countdown to clients. Ideas anyone?
[HttpGet]
public IHttpActionResult CancelCountdown()
{
// DOES NOTHING BECAUSE THERE'S A NEW INSTANCE OF THE CONTROLLER
timer.Stop();
timer.Dispose();
return Ok();
}
private void StartCountdown()
{
// MAY BE A BAD SOLUTION BECAUSE THE APP POOL MAY RECYCLE
timer.Interval = _timeIntervalInMilliseconds;
timer.Elapsed += BroadcastToClients;
timer.Start();
}
private void BroadcastToClients(object sender, EventArgs e)
{
_elapsed += 1;
if (_elapsed == _duration)//_duration is 60
{
timer.Stop();
timer.Dispose();
return;
}
_messageHub.Clients.All.shutdown(_elapsed);
}
It's kind of hard to provide an adequate solution without knowing what you're trying to accomplish with this, but i'll give it a shot.
As Luaan pointed out, controllers are designed to be essentially stateless, so you shouldn't put instance variable on them except for it's external dependencies, since each request creates a new instance of the controller class.
You could store the timer on a static dictionary, indexed by a GUID, and return the GUID on your controller and use it as the cancellation token.
Something like:
private static Dictionary<string,Timer> timers = new Dictionary<Guid,Timer>();
public Guid StartCountdown()
{
// MAY BE A BAD SOLUTION BECAUSE THE APP POOL MAY RECYCLE
timer.Interval = _timeIntervalInMilliseconds;
timer.Elapsed += BroadcastToClients;
var guid = Guid.NewGuid().ToString();
timers.Add(guid,timer);
timer.Start();
return guid;
}
public IHttpActionResult CancelCountdown(Guid cancelationToken)
{
//If the timer no longer exist or the user supplied a wrong token
if(!timers.HasKey(cancelationToken)) return;
var timer = timers[cancelationToken];
timer.Stop();
timer.Dispose();
timers.Remove(cancelationToken);
}
However this won't solve the problem with the AppPool recycling. For a more robust solution, instead of using a timer, you could store the start date and time of each countdown in a more permanent storage (say an SQL database, a NoSQL databse, a redis server or whatever), and have a running thread or global timer, or something like Hangfire, initialized on startup, that constantly checks your countdown storage. If enough time has passed to send a broadcast message you send it, and mark the countdown as finished. If a user wants to cancel the countdown, the controller will simply read the appropiate record, mark it as cancelled, and your running thread can ignore it.
If you go with this approach, you'll need to take into account some considerations:
If the timer interval is set too short you could have a perfomance bottleneck for having to access a permament storage too often. If the interval is too long, the countdown won't be too precise.
To alleviate this problem you could store the countdowns start time in permanent storage, in case the app pool resets and you need to restore them. And also have them stored in memory on a static variable for quicker access.
Please note that if you're working with a server farm instead of a single server, static variables won't be shared across instances.

WPF DispatcherTimer Memory Issue

Edit: If useful, this project is on GitHub at https://github.com/lostchopstik/BetterBlync
I am building an application for the Blync status light using their provided API. This application polls the Lync/Skype for Biz client and converts the status to the appropriate light color. All aspects thus far work as expected, however when I leave this program running for an extended period of time, the memory usage grows until a System.OutOfMemory exception occurs.
I have narrowed the problem down to the DispatcherTimer holding the timer in memory and preventing it from being GCed. After reading some things online I found you could manually call for garbage collection, but this is bad practice. Regardless, here is what I have in my code right now:
private void initTimer()
{
timer = new DispatcherTimer();
timer.Interval = new TimeSpan( 0, 0, 0, 0, 200 );
timer.Tick += new EventHandler( Timer_Tick );
timer.Start();
}
private void Timer_Tick(object sender, EventArgs e)
{
// Check to see if any new lights are connected
blync.FindBlyncLights();
// Get current status from Lync client
lync.GetStatus();
// Change to new color
setStatusLight();
if ( count++ == 100 )
{
count = 0;
GC.Collect();
}
}
The timer ticks every 200ms. I commented out all methods inside the timer and just let it run empty, and it still burned memory.
I am wondering what the proper way to handle this timer is. I've used the DispatcherTimer in the past and not had this issue.
I would also be open to trying something besides the DispatcherTimer.
If it is also useful, I have been messing with MemProfiler and here as my current graph with manual GC:
http://imgur.com/Iut91mF
It's a little hard to tell without seeing the rest of the code or the class the timer belongs to. I don't see anywhere you call Stop() on the timer. Does it need to be stopped?
You could also keep a local reference to the timer in whatever class you're in and call Start() and Stop() as needed.
If the timer never needs to be stopped and runs indefinitely, I would certainly look at what you're allocating as the timer runs and that's probably where your issue is.

How to raise an event at any given time

I'm trying to raise an event at a given time in my windows store app. Now I've done this in desktop apps countless times, and I've used System.Threading.Timer in the past and it has worked well, but that class is not available to windows store apps.
I have looked in the documentation and found a class called DispatchTimer and although it appears to be what I'm after, correct me if I'm wrong but the docs are lacking. But luckily it's pretty easy to use.
So I tried the DispatchTimer, but after using it, I'm not even sure this is what I should be using.
How can I watch for any given time and raise an event when that time is up (in a windows store app)? And do you know of any resources that do this in a metro app?
Use DispatcherTimer like this:
var timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(10) };
timer.Tick += OnTimerTick;
timer.Start();
private void OnTimerTick(object sender, object args)
{
// Do something with pickup here...
}
This will create a timer with intervals of 10 seconds.
The DispatcherTimer is the way to go. Notice that if you want your app to run in background you must declare that on the app manifest or use Background agents.

How to make my wpf app wait for 3 minutes before re-loading data?

I am using VS2010 - WPF - C#
in my application I fetch data from a web server and view it on my interface
the problem is that I want to keep fetching data and keep refreshing my interface every 3 minutes but I don't know how to do that...
I tried (Thread.Sleep(18000)) and it didn't work because my interface wouldn't show at all
I don't know how to use the Timer for such reason and I couldn't find what I'm looking for elsewhere
Please can you help me with it ?
Best Regards
What programming model? Stock or something more sane with a MVVM approach?
Anyhow, use a TIMER to request a callback after 3 minutes. In the callback invoke back to the dispatcher thread of the window once you got the results of the web service call. Finished.
Use a DispatcherTimer, there are also examples how to use it on the given link
Use a dispatch timer like this
Delcare it
public System.Windows.Threading.DispatcherTimer timer1;
In the constructor
timer1 = new System.Windows.Threading.DispatcherTimer();
timer1.Interval = TimeSpan.FromSeconds(180); // 3 mintues interval
timer1.Tick += TimerTicked; // Event for handling the fetching data
Do your job
private void TimerTicked(object sender, EventArgs args)
{
//Fetch the data
}
timer1.start(); // Whereever you want to start the timer

Categories