Timer Tick Event and Thread in WinForms - c#

I have a timer named SendTimer, the interval is 30 secs.
protected void SendTimer_Tick(object sender, eventArgs e)
{
SendTimer.Enabled = false;
TransferMoney();
System.Threading.Thread.Sleep(15000);
GenerateTransactions();
SendTimer.Enabled = true;
}
I expected tick event to be called correctly by one thread at the same time. NOT by 2 threads simultaneously. but as I saw in my LOGS it seems to be called by a thread while another thread was in action. Any Idea? Because I disable and enable it respectively.

Windows Forms Timer is a single-threaded by definition. It has nothing about multithreading, because it elapses via WM_TIMER message, being sent to current GUI thread message queue.
So, this:
NOT by 2 threads simultaneously
is incorrect, because even if you have several threads, WinForms Timer has nothing to do with this.

Related

Can System.Timers.Timer elapsed event if previous event still working?

Can System.Timers.Timer elapsed event if previous event still working?
For example, i set Interval 100 ms, but code in handler works 200 ms.
_taskTimer = new System.Timers.Timer();
_taskTimer.Interval = 100;
_taskTimer.Elapsed += _taskTimer_Elapsed;
void _taskTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
Work(); // works 200 ms.
}
Is timer "wait" while Work() method ends? Or execute a new one?
Thank you!
System.Timers.Timer(Multi Threaded Timer) is multithreaded timer. that means it executes it elapse event on multiple thread and that means it don't wait for previous elapse event.
if you want to wait for previous elapse event to complete that you can use System.Windows.Timer (Single Threaded Timer) - this is single threaded timer will execute event on single thread only(UI thread) which created timer.
You can read more about this here : Timers written by Joe Albahari
Internally system.timers.timer also uses system.threading.timers, so the execution process continues even after elapsed fires new execution.
Have a look at the source code of System.Timers.Timer: Timers.Cs
It will Continue Executing on different thread
For reference you can visit this page

Windows Form application C# stops responding in between timer tick events

I have a code in which I have started a timer tick event of 75 sec. The application is supposed to perform a task, at a time interval of 75 sec. The application just runs fine sometimes for 5 hrs, however all of a sudden it shows not responding...whenever other operations are done on the computer like opening other files...
My code looks like this:
private void button2_Click(object sender, EventArgs e)
{
tmrTimer.Enabled = true;
}
private void tmrTimer_Tick(object sender, EventArgs e)
{
//Do my stuff here;
}
I think it maybe because you used Timer from System.Windows.Forms.Timer class. This kind of Timers are Single Thread Timers; which means they use the same thread that your UI use. So, it's obvious why your application shows not responding when the thread has lots of things to do.
I suggest to change the timer type and try this one: System.Threading.Timers.

Timers.Timer stopped triggering elapsed event and !Threads showing 1023 unstarted and pending threads

my application has a Timers.Timer implementation as in this question which seems to stop triggering its elapsed event after some time (days or weeks) [the elapsed event is supposed to run every 60 seconds see this for details]
0:000> !threads -live
ThreadCount: 1041
UnstartedThread: 1023
BackgroundThread: 11
PendingThread: 1023
DeadThread: 3
Hosted Runtime: no
Later, we found out that when the the elapsed event stopped getting fired, the number of unstarted and pending threads also rise consistently until 1023 limit is reached. Then the process gets stuck.
What is the cause/reason or the relation between my Timer not firing the event and the eventual rise in the # threads (unstarted and pending)?
Almost certainly your timer event handler is not exiting. Either it's blocking (in a Sleep or waiting on some event), or it's gone into an infinite loop. Then the next timer event comes along and it either blocks or goes into an infinite loop. Etc . . .
You can determine if this is the case by changing your timer event handler so that it tells you if it's re-entered:
private bool _inTimer = false;
private void TimerTick(object Sender, ElapsedEventArgs e)
{
if (_inTimer)
{
// there's already a timer running.
// log a message or notify you in some other way.
}
_inTimer = true;
// do your processing here
// and then clear the flag
_inTimer = false;
}
That will tell you if what I suspect is the case. But don't use it as a production way to prevent concurrent timer instances, though. There's a race condition with the Boolean flag. If you want to prevent concurrent timer ticks, disable the timer when you enter the method, and then re-enable it when you exit. Like this:
private void TimerTick(object Sender, ElapsedEventArgs e)
{
_myTimer.Enabled = false;
// do processing
// then re-enable the timer
_myTimer.Enabled = true;
}
On a related note, the other thing that can cause your timer to appear to stop functioning is that it throws an exception which the runtime library squashes without surfacing. That behavior is documented:
The Timer component catches and suppresses all exceptions thrown by event handlers for the Elapsed event. This behavior is subject to change in future releases of the .NET Framework.
So if an exception goes uncaught in your event handler, it's dropped on the floor. It's for this reason that I recommend against using System.Timers.Timer. I would suggest using System.Threading.Timer instead, as it doesn't suffer from this idiotic design.
I ended up revising/revamping the Timer implementation and use a Thread with a do-while loop, instead. This will avoid the 'unknown' problems we are getting from the Timers elapsed event not firing up.
Thanks all

Creating a background timer to run asynchronously

I'm really struggling with this. I'm creating a winforms application in visual studio and need a background timer that ticks once every half hour - the purpose of this is to pull down updates from a server.
I have tried a couple of different approaches but they have failed, either due to poor tutorial/examples, or to my own shortcomings in C#. I think it would be a waste of time to show you what I have tried so far as it seems what I tried was pretty far off the mark.
Does anyone know of a clear and simple way of implementing an asynchronous background timer that is easily understandable by a C# newbie?
// Create a 30 min timer
timer = new System.Timers.Timer(1800000);
// Hook up the Elapsed event for the timer.
timer.Elapsed += OnTimedEvent;
timer.Enabled = true;
...
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
// do stuff
}
with the usual caveats of: timer won't be hugely accurate and might need to GC.KeepAlive(timer)
See also: Why does a System.Timers.Timer survive GC but not System.Threading.Timer?
Declare member variable in your form:
System.Timers.Timer theTimer;
On form load (or whatever other time you need to start update polling), do:
theTimer = new System.Timers.Timer(1800000);
theTimer.Elapsed += PollUpdates;
theTimer.Start();
Declare your PollUpdates member function like this:
private void PollUpdates(object sender, EventArgs e)
{
}
I think you need to know about all timer classes. See Jon's answer below.
What kind of timer are you using?
System.Windows.Forms.Timer will execute in the UI thread
System.Timers.Timer executes in a thread-pool thread unless you
specify a SynchronizingObject
System.Threading.Timer executes its callback in a thread-pool thread
In all cases, the timer itself will be asynchronous - it won't "take up" a thread until it fires.
Source: Do .NET Timers Run Asynchronously?

Background timer to update UI?

I got a little problem with my application.
I would like to update something on my UI every 10 seconds. I first used a DispatcherTimer for this but it will block my UI for a short time because the update method needs to load something from the web and this operation needs some time.
Now I thought about some kind of background worker and I found BackgroundTasks.
The problem with Background tasks is, as far as I understood it correctly, that they are supposed to serve as updaters even if the app is suspended. I don't need that.
I only would like to update if my app is running not if it is suspended.
Is there a good way to solve this?
Any suggestions what to use for this?
Thanks in advance!
You need two things for it:
Timer
You can update the UI in System.Timers.Timer with the 10 seconds interval.
Dispatcher
You need to use Dispatcher.Invoke to change the UI without holding the main UI thread. Instead the method Process should be called on a separate thread (Timer method), other than main UI thread, and use Dispatcher in it to alert main UI thread for the change.
Process() // method to be called after regular interval in Timer
{
// lengthy process, i.e. data fetching and processing etc.
// here comes the UI update part
Dispatcher.Invoke((Action)delegate() { /* update UI */ });
}
You need to create a thread that runs the part of your code that gets and processes the information from the website. This way, your form will not hesitate because it will be on a different thread than the processing part.
This Article on code-project should get you started.
Also, you could start a timer, which has a elapsed event, that occurs every time the timer passes a certain time cycle.
http://www.dotnetperls.com/timer
The other answers are missing proper cleanup: When the timer fires in the exact moment that the window was closed, I would get an uncaught TaskCanceledException when trying to run Dispatcher.Invoke. I didn't find help for this problem in other questions. I was able to solve it by unregistering the timer callback when closing the window.
public partial class MainWindow : Window
{
Timer clockTimer = null;
public MainWindow()
{
clockTimer = new Timer(1.0); // 1 ms update to test for TaskCanceledException
clockTimer.Elapsed += Timer_Elapsed;
clockTimer.AutoReset = true;
clockTimer.Start();
Closed += (object sender, EventArgs e) => { clockTimer.Elapsed -= Timer_Elapsed; };
}
private void Timer_Elapsed(object sender, ElapsedEventArgs e) {
var now = DateTime.Now;
Dispatcher.Invoke((Action)delegate () {
UpdateTime(now);
});
}
}
Obviously this is not a good idea if the window was re-shown. I tried adding a dtor, but it would never get called, probably due to cyclic dependencies.
Disclaimer: I don't know C#, so this might not be the best or proper way of doing things.

Categories

Resources