. NET built-in timer type will occur callback method rushed into

Source: Internet
Author: User

Analyze problems

The so-called method re-entry is a concept about multithreaded programming. When multiple threads are running concurrently in a program, it is possible that the same method can be called simultaneously by multiple threads. When there are some non-thread-safe code in this method, the method re-entry will result in inconsistent data, which is a very serious bug.

In the previous article, the author has briefly introduced. NET built-in timer types, which are:

1, System.Windows.Forms.Timer.

2, System.Threading.Timer.

3, System.Timers.Timer.

These three types of timing methods are different, here the author analyzes whether there are three types of methods to re-enter the situation.

1, System.Windows.Forms.Timer type.

In the previous article, I have introduced the System.Windows.Forms.Timer type of timing mechanism is the current UI thread of the message queue inserted a timed message, such a mechanism to ensure that the single-threaded run environment. In this case, the time interval of the timer timer is set to the minimum, and after a timed message must wait for the previous message to finish processing. So in this case, the callback method will not be re-entered in the case.

2. System.Threading.Timer's callback method executes on a worker thread, and whenever a timed event occurs, the thread that controls the System.Threading.Timer object is responsible for assigning a new worker thread from the thread pool, which is a typical multithreaded programming environment, so the method weighs The phenomenon of the entry is likely to occur. This requires programmers to be aware of thread synchronization issues when writing callback methods for System.Threading.Timer type objects.

3, System.Timers.Timer type.

The System.Timers.Timer type can be thought of as a package type of System.Threading.Timer, which can be set by a synchronization block, at which point the properties are very similar to System.Windows.Forms.Timer and do not occur when the callback method is re-entered. Case When its synchronous fast property is not set, its callback method is executed on a worker thread, and its callback method may result in a re-entry.

The following code shows the re-entry of the System.Threading.Timer type and the System.Timers.Timer type.

usingSystem;namespacetest{classReenter {//static members that are used to cause thread synchronization problems        Private Static intTestInt1 =0; Private Static intTestInt2 =0; Static voidMain () {Console.WriteLine ("System.Timers.Timer callback method re-entry test:");            Timerstimerreenter (); //This ensures that the callback method that has started has an opportunity to endSystem.Threading.Thread.Sleep ( -); Console.WriteLine ("System.Threading.Timer callback method re-entry test:");            Threadingtimerreenter ();        Console.read (); }        /// <summary>        ///Show System.Timers.Timer callback method re-entry/// </summary>        Static voidTimerstimerreenter () {System.Timers.Timer Timer=NewSystem.Timers.Timer (); Timer. Interval= -;//100 msTimer. Elapsed + =Timerstimerhandler; Timer.            Start (); System.Threading.Thread.Sleep ( -);//run for 2 secondstimer.        Stop (); }        /// <summary>        ///Show System.Threading.Timer callback method re-entry/// </summary>        Static voidThreadingtimerreenter () {using(System.Threading.Timer timer=NewSystem.Threading.Timer (NewSystem.Threading.TimerCallback (Threadingtimerhandler),NULL,0, -) {System.Threading.Thread.Sleep ( -);//run for 2 seconds            }        }        Static voidThreadingtimerhandler (ObjectState ) {Console.WriteLine ("Test integer: {0}", testint2.tostring ()); //Sleep 10s, guaranteed method re-entrySystem.Threading.Thread.Sleep (10000); TestInt2++; Console.WriteLine ("test integer after increment 1: {0}", testint2.tostring ()); }        /// <summary>        ///callback method for System.Timers.Timer/// </summary>        Static voidTimerstimerhandler (Objectsender, EventArgs e) {Console.WriteLine ("Test integer: {0}", testint1.tostring ()); //Sleep 10s, guaranteed method re-entrySystem.Threading.Thread.Sleep (10000); TestInt1++; Console.WriteLine ("test integer after increment 1: {0}", testint1.tostring ()); }    }}

In the above code, in order to ensure that the timer callback method execution time longer than the timer interval, added to let the thread sleep 1s code:

System.Threading.Thread.Sleep (+);

In this case, the output will be very different from what is expected, and multiple callback methods will execute in parallel and cannot control their order:

  

  

As the output shows, the result of all callback methods executing in parallel is that the order of execution is disorganized and that the global variables of the operation may be modified in other threads. To avoid this, the programmer needs to add a lock lock for the callback method, as shown in the following code:

Private Static ObjectLockobj =New Object(); /// <summary>        ///callback method for System.Threading.Timer/// </summary>        /// <param name= "state" ></param>        Static voidThreadingtimerhandler (ObjectState ) {            Lock(Lockobj) {Console.WriteLine ("Test integer: {0}", testint2.tostring ()); //Sleep 10s, guaranteed method re-entrySystem.Threading.Thread.Sleep (10000); TestInt2++; Console.WriteLine ("test integer after increment 1: {0}", testint2.tostring ()); }        }        /// <summary>        ///callback method for System.Timers.Timer/// </summary>        Static voidTimerstimerhandler (Objectsender, EventArgs e) {            Lock(Lockobj) {Console.WriteLine ("Test integer: {0}", testint1.tostring ()); //Sleep 10s, guaranteed method re-entrySystem.Threading.Thread.Sleep (10000); TestInt1++; Console.WriteLine ("test integer after increment 1: {0}", testint1.tostring ()); }        }

In the case of a synchronous lock, it is guaranteed that only one thread can execute the callback method at all times, while the other threads will be forced to block the wait, which is the output after locking:

As the reader sees, the output after the lock is regular, the problem of thread synchronization is solved, but the reader may already feel when running the program, the lock essentially cracked the parallel advantage of multithreading, making the execution of the program become relatively slow. So when writing timer code, programmers should carefully consider when to lock, and the appropriate need to ensure that multithreading parallel operation.

Answer

In. NET built-in timers, the System.Timers.Timer and System.Threading.Timer two types may have a callback method re-entry problem, and System.Windows.Forms.Timer does not have this problem.

When designing a timer, you need to consider whether you need to lock the callback method and how to lock it, the less code that is locked in principle, the smaller the effect on efficiency.

  

. NET built-in timer type will occur callback method rushed into

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.