. The difference and usage of three kinds of timer in net

Source: Internet
Author: User
Tags message queue

1. Implement a timer that raises events at user-defined intervals. This timer is best used in Windows Forms applications and must be used in Windows.
System.Windows.Forms.Timer

2. Provides a mechanism for executing a method at a specified time interval. This class cannot be inherited.
System.Threading.Timer

3. Generate recurring events in the application.
System.Timers.Timer

These three timers are located in a different namespace, which probably describes the purpose of the 3 timers, the first of which is a control that can be used only in Windows Forms. In the. NET1.1, the 3rd System.Timers.Timer can also be dragged and used, and. NET2.0 start canceling, you can only write code manually. There are no restrictions on the other 2. The following through the specific examples of the use of 3 timer and the difference between the online talk a lot, but basically no code.

A System.Windows.Forms.Timer

#region System.Windows.Forms.Timer
public partial class Form1:form
{
Public Form1 ()
{
InitializeComponent ();
}

int num = 0;

private void Form_timer_tick (object sender, EventArgs e)
{
Label1. Text = (++num). ToString ();
Thread.Sleep (3000);
}

private void Button1_Click (object sender, EventArgs e)
{
Form_timer.start ();
}

private void Button2_Click (object sender, EventArgs e)
{
Form_timer.stop ();
}
}
#endregion
This is a very simple function, in the form of a System.Windows.Forms.Timer control is dragged on the name of Form_timer, in the Properties window set the Enable property to Ture,interval is the time interval of the timer. Double-click on the control to see the Form_timer_tick method. In this method, we let her keep adding a number and display it on the form, and 2 buttons provide the control function of the timer.

Execute the time you go to click on the other form back and you will find our form is out of response. Because we use Thread.Sleep (3000) Here, the current thread hangs, and the UI loses its corresponding, which means that the execution of this is a single thread. The thread that executes the timer is the UI thread.

The Timer is used to trigger events at user-defined event intervals. Windows timers are designed for single-threaded environments where the UI thread is used to perform processing. It requires that the user code have an available UI message pump and always operate on the same thread, or marshal the call to another thread.

A tick event is defined inside the timer, which actually adds a line of code when we double-click the control in front of it.

This. Form_timer.tick + = new System.EventHandler (this. Form_timer_tick);
This should understand, do not understand can see my blog about the Commission and events of the article. Windows then associates the timer with the calling thread (the UI thread). When the timer is triggered, Windows inserts a timer message into the thread message queue. The calling thread executes a message pump to extract the message and then sends it to the callback method (the Form_timer_tick method here). And these are single-threaded, so the UI will feign death when the callback method is executed. Therefore, it is not appropriate to use this control to calculate restricted or IO-constrained code, because it is easy to cause the interface to suspend animation, but should use multi-threaded timer. It is also important to note that this control has a low time accuracy and is limited to 55 milliseconds. We set the interval to 20ms and then record the current time in the start and stop methods, and calculate the run time:





From the above figure can see the program executed 7.8S is 7800ms, and the interval is 20ms, that is, the last display number should be about 390, but only 250, is obviously inaccurate, but according to MSDN said 55ms accuracy, 7800ms should only perform more than 140 times or less. I wonder if there is a problem in understanding this.

Two System.Timers.Timer

Next we'll look at another timer, and we'll use him to rewrite the program.

#region System.Windows.Forms.Timer
public partial class Form1:form
{
Public Form1 ()
{
InitializeComponent ();
}

int num = 0;
DateTime time1 = new DateTime ();
DateTime time2 = new DateTime ();
Defining a Timer
System.Timers.Timer Timers_timer = new System.Timers.Timer ();

private void Button1_Click (object sender, EventArgs e)
{
Set timer manually to start execution
Timers_timer.interval = 20;
Timers_timer.enabled = true;
timers_timer.elapsed + = new System.Timers.ElapsedEventHandler (timers_timer_elapsed);
time1 = DateTime.Now;
}

void Timers_timer_elapsed (object sender, System.Timers.ElapsedEventArgs e)
{
Label1. Text = convert.tostring ((++num)); Show to Lable
Thread.Sleep (3000);
}

private void Button2_Click (object sender, EventArgs e)
{
Stop execution
timers_timer.enabled = false;
Time2 = DateTime.Now;
MessageBox.Show (Convert.ToString (time2-time1));
}
}
#endregion
We can see that this code is basically the same as the previous use of Form.timer, but the difference is that we are manually defining the object, not by pulling the control. He also has the interval, the Enabled and other attributes, the function and the first is the same. The difference is that his event is named elapsed, but as with the tick above, the method of binding a delegate. It's just that we do it manually here. Another difference is that Form.timer can be controlled with the stop and start methods, which are controlled by the Enable property. But you can actually use the stop and start methods, and the interior is controlled by his own enable.

The biggest difference is that the above code will error when debugging, prompting you to "Invalid between threads: Access it from a thread that is not creating the control" Label1 ". "But if you do not debug the direct run is OK, and the run-time you go to drag the form will find no animation appears." From here we can know that the timer's creation thread and execution thread are not the same thread. That is, multithreading is used. The timer's creation thread is the UI thread, and the execution thread is the thread in the Theardpool, so it does not feign animation, but it will error when debugging because the non-control's creation thread cannot manipulate the control. But you can run it directly, and here is VS05 doing the hands and feet. There are many solutions, with delegate. BeginInvoke () and so on. Here is a unique method to set the Timer's SynchronizingObject property, Timers_timer.synchronizingobject = Label1; So, in our words, the debug run will not be an error, But with this property set, the timer is programmed for single-threaded invocation, basically the same as the first one.

The Timer is designed for use in a multithreaded environment for worker threads. Server timers can move between threads to handle the Elapsed event that is raised, which can cause events to be raised more accurately on time than the Windows timer. The Elapsed event is raised on the ThreadPool thread. If the Elapsed event is processed longer than Interval, this event will be raised again on another ThreadPool thread. Therefore, the event handlers should be reentrant.

In addition, different from the previous phenomenon is 1 after each addition and does not stop 3 seconds in the display. But continue to show, just slightly slower. Because we set the interval to 20ms, and the execution time is 3s, it will continue executing in the other thread after 20ms, and the current thread is suspended. With regard to the accuracy of the timer, cancel the suspension of 3s and find that the result is basically the same as the first one.

Three System.Threading.Timer

Continue to use this object to retrofit the program.

#region System.Windows.Forms.Timer
public partial class Form1:form
{
Public Form1 ()
{
InitializeComponent ();
}

int num = 0;
DateTime time1 = new DateTime ();
DateTime time2 = new DateTime ();
System.Threading.Timer Thread_time;

private void Button1_Click (object sender, EventArgs e)
{
Start
Thread_time = new System.Threading.Timer (thread_timer_method,null,0,20);
time1 = DateTime.Now;

}

void Thread_timer_method (Object o)
{
Label1. Text = convert.tostring ((++num));
System.Threading.Thread.Sleep (3000);
}

private void Button2_Click (object sender, EventArgs e)
{
Stop it
Thread_time.dispose ();
Time2 = DateTime.Now;
MessageBox.Show (Convert.ToString (time2-time1));
}
}
#endregion
When using Threading.timer, the method is not the same as before, so the parameters are all set in the constructor, and the start time can be set. The start and stop methods are not provided to control the timer. And it is implemented in a way that is a callback method, rather than an event. There is still a difference between them.

We only have to destroy the object to stop him. When you run, you will find him and the front of the Timers.timer, is multi-threaded, mainly in the performance will not be suspended animation, debug run error. But to your surprise, our code didn't stop her. Calling the Dispose method is not a use. What's the problem? Then there was a test that modified the interval to 100,200,500,1000,3000,4000. These situations. It is found that when the interval is above 500ms, the basic is stopped immediately. The shorter the interval relative to the execution time, the longer it takes to proceed. This should be caused by multiple threads running when the interval is less than the execution time. Because all threads are not stopped at the same time. The shorter the interval, the more threads, so the more execution times.



Finally, let's look at another special place for this object.

static void Main ()
{
Timer T = new timer (test,null,0,1000);
Console.ReadLine ();
}

public static void Test (Object o)
{
Console.WriteLine ("Nihao");
Gc. Collect ();
}
What results does this code output? By default he only outputs it once and stops. Why is it? According to the above, when the object T is defined, after executing the code, it is forced garbage collection, because T has no other reference in main, so it is recycled. But if we do, the compiler's "optimize" item is canceled, look at the situation. The program is always output. Why does garbage collection not be recycled? Because of this disabling optimization option, the declaration period of T is extended to the end of the method. So it always executes.

Because the compiler is optimized by default, we must ensure that the timer object is always referenced and not garbage collected. So we can use the compiler to open the optimization case, at the end of the main function plus t=null guaranteed to be referenced before recycling, but you find that this is useless. Because the JIT compiler optimizes the t=null to be removed directly, so we use T. Dispose (), you can achieve your goal. When we do garbage collection, the CLR discovers that T is also referenced and does not execute dispose so it will not be recycled. It is the case that Threading.timer sometimes runs once or it is destroyed, and is also related to compiler optimizations, so be careful when using it.

Finally, take a look at the MSDN Description: Whenever you use a Timer, you must keep a reference to it. For any managed object, the timer is garbage collected if there is no reference to the timer. Even if the Timer is still active, it will be recycled. When the timer is no longer needed, use the Dispose method to release the resource held by the timer. If you want to receive a signal when the timer is released, use the Dispose (WaitHandle) method overload that accepts WaitHandle. After the timer has been released, the WaitHandle is terminated.



Summarize:

System.Threading.Timer is a simple light-weight timer that uses callback methods and is serviced by thread pool threads. It is not recommended for use with Windows forms because its callbacks do not take place on the user interface thread. System.Windows.Forms.Timer is a better choice for Windows forms. To get the server-based timer feature, consider using System.Timers.Timer, which can raise events and have additional functionality.

The 3 timers are mentioned in "CLR Via C #", but the author says System.Timers.Timer is a System.Threading.Timer, not recommended, but in my Web project Application_ I still use this instead of threading.timer in start, because when I use Threading.timer, I do not execute it once.

For the use of the timer in the B/s structure is more complex, generally we put the timer in the Application_OnStart, so that the global maintenance of a timer, you can regularly back up the database, regular maintenance users and other operations, and the method of writing static, so as not to be garbage collection. It is not recommended to use in the General ASPX page, because the server-side timer is not very meaningful to the user, you can use JS instead. And every request on this page could introduce a new timer, causing the system to crash. In addition, the timer is an ASP. IIS-related, so for important execution tasks, it is recommended to write a service or stand-alone program on the server to execute.

Original address: http://blog.itpub.net/12639172/viewspace-571197

. The difference and usage of three kinds of timer in net

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.