System.Timers.Timer is a multi-threaded timer, if a timer is not processed to complete, to the next point in time, the new timer will also be started, so you need to pay attention when using the timer.
The following example shows how a timer is used.
usingSystem;usingSystem.Threading;usingSystem.windows;namespace timerexp{// <summary> /// MainWindow.xaml's interactive logic // </summary> Public Partial classMainwindow:window {System.Timers.Timer Timer; Public MainWindow() {InitializeComponent ();if(Timer = =NULL) {timer =NewSystem.Timers.Timer (); Timer. Interval = +; Timer. Elapsed + = timer_elapsed; } }voidTimer_elapsed (Objectsender, System.Timers.ElapsedEventArgs e) {thread.sleep ( the);stringCurrentthreadid = Thread.CurrentThread.ManagedThreadId.ToString (); This. Dispatcher.begininvoke (NewAction (() = { This. Label_result.content + = Currentthreadid +","; }),NULL); }Private void Button_click_1(Objectsender, RoutedEventArgs e) {timer. Start (); } }}
is the running result of the instance.
The text box in the figure shows the current thread ID of the running timer. You will find that the timer will run on a different thread. If you remove the code from the Timer_elapsed method with the CPU resting for 3 seconds, you will find that the timer will run in the same thread. This is because the timer in the instance executes the Timer_elapsed method every second, and the timer will run the Timer_elapsed method in the new thread when the current run has not left the timer_elapsed method. If the previous run has left the Timer_elapsed method, the Timer_elapsed method will continue to run on the same thread. Therefore, the timer is more suitable for less time-consuming small tasks, if running time-consuming tasks in the timer, it is very easy to cause the multi-threaded re-entry problem due to timeouts, that is, multiple threads simultaneously into the timer_elapsed method.
To deal with multi-threaded re-entry issues. You can lock or increase the flag bit.
The following code shows a solution that uses a flag bit.
int Intimer =0;void Timer_elapsed (object sender, System. Timers. Elapsedeventargse) {if (interlocked. Exchange(Ref Intimer,1) ==0) {Thread. Sleep( the);String currentthreadid = Thread. CurrentThread. Managedthreadid. ToString();This. Dispatcher. BeginInvoke(new Action () = {This. Label_result. Content+ = Currentthreadid +",";}), NULL);Interlocked. Exchange(Ref Intimer,0);} }
If you use "Intimer = 0" To assign a variable intimer directly, in a multithreaded environment, the same problem. Interlocked.exchange provides a lightweight, thread-safe way to assign values to objects, so use Interlocked.exchange to assign values to variables.
Example of multithreaded timer System.Timers.Timer.