I’m writing an application which requires a status bar update for while a database is being loaded. I set the label to “Database loading…” then load the database with a BackgroundWorker. When the worker completes, I set the label to “Database loaded.” This is only done on startup, however, and I don’t want the label to be visible for much longer, and would like it cleared several seconds after the worker completes. I could put a dedicated timer object on my main for, but this single action would be its only job, and it seems like a more elegant solution should exist. So I tried lambdas:
void dataLoader_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
DataLabel.Text = "Database Loaded";
System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
timer.Interval = 5000;
timer.Tick += new EventHandler((o, a) =>
{
DataLabel.Text = "";
(o as System.Windows.Forms.Timer).Enabled = false;
});
}
Of course timer‘s scope expires after the function exits, and it’s Tick event is never called.
How can I get a simple, single-fire event to run without the use of global-instance timers?
Your code is mostly fine. In fact, your general architecture is the most elegant solution in my opinion. You just forgot to start the timer. You do not need to worry about the GC prematurely collecting the timer because it will actually “root” itself automatically when it is started. That of course begs the question of whether or not this would cause a memory leak since a new timer is created everytime. I think not since the timer will also “unroot” itself when it is stopped. So the following should work fine.