C # provides three types of Timers:
1. Windows-based standard timer (system. Windows. Forms. Timer)
2. server-based timer (system. Timers. Timer)
3. Thread timer (system. Threading. Timer)
Next I will use some small experiments to analyze the similarities and differences between the three timers, especially those related to threads.
Example:
I,Windows-based standard timer (system. Windows. Forms. Timer)
Note that the windows timer isSingle threadEnvironment Design
This timer exists in this product since Visual Basic 1.0 and has not been modified.
This timer is the easiest way to use. You only need to drag the timer control in the toolbox to the form, and set the attributes such as event and interval.
The results of the experiment fully conform to the characteristics of a single thread:
1. When this timer is started, the subthread ID is displayed in the subthread ID list in the lower end, and is the same as the primary thread ID.
Private void formstimer_tick (Object sender, eventargs E)
{
I ++;
Lblsubthread. Text + = "subthread execution, thread ID:" + system. Threading. thread. currentthread. managedthreadid. tostring () + "\ r \ n ";
}
2. After you click the main thread to pause for 5 seconds, the sub-thread will pause the execution, and the sub-thread will not be paused after 5 seconds, instead, execute the subthread directly (that is, a few lines of value will be output)
System. Threading. thread. Sleep (5000 );
3. Suspending the sub-process event for 5 seconds will result in no response for the main window for 5 seconds.
4. Define a static thread variable:
[Threadstatic]
Private Static int I = 0;
Add one in the subthread event, and click the static variable value of the thread to obtain the added I value.
II,Server-based timer (system. Timers. Timer)
System. Timers. Timer does not rely on the form. It is used to wake up the thread from the thread pool. It is the updated version after the traditional timer is optimized to run in the server environment.
No ready-made controls are provided in the vs2005 toolbox and need to be manually coded to use this timer
You can use either of the following methods,
1. The synchronizingobject attribute is attached to the form.
System. Timers. Timer timerstimer = new system. Timers. Timer ();
Timerstimer. Enabled = false;
Timerstimer. interval = 100;
Timerstimer. elapsed + = new system. Timers. elapsedeventhandler (timerstimer_elapsed );
Timerstimer. synchronizingobject = this;
In this way, the experiment works almost the same as the windows-based standard timer, but in the second experiment above, although the sub-thread execution will be suspended, however, after five seconds, all the previously queued tasks are executed (That is, it will not output a few rows of values.)
2. Do not use the synchronizingobject attribute
This is a multi-threaded approach, that is, the starting sub-thread and the main form are not in one thread. However, there is also a problem: Because the subthread is a separate thread, it cannot access the controls in the form and can only be accessed through proxy:
Delegate void settextcallback (string text );
.
.
Void timerstimer_elapsed (Object sender, system. Timers. elapsedeventargs E)
{
// Use proxy
String text = "subthread execution, thread ID:" + system. Threading. thread. currentthread. managedthreadid. tostring () + "\ r \ n ";
Settextcallback d = new settextcallback (settext );
This. Invoke (D, new object [] {text });
I ++;
}
Private void settext (string text)
{
Lblsubthread. Text + = text;
}
In this way, the following results will be obtained after the experiment again:
1. When this timer is started, the subthread ID is displayed in the subthread ID list in the lower end, and is different from the primary thread ID.
2. After you click the main thread to pause for 5 seconds, the sub-thread will continue to execute (the interface can not be seen, but it can be easily seen by outputting files in the sub-thread)
3. Suspending the sub-process event for 5 seconds does not cause no response to the main window.
4. In a subthread event, add a static variable to the thread each time, and click whether the value of the static variable in the thread is 0 (the static variable in the main window will not be changed)
III,Thread timer (system. Threading. Timer)
The thread timer does not depend on the form. It is a simple and lightweight timer that usesCallback MethodInstead of using events, they are supported by thread pool threads.
Thread timers are very useful in scenarios where messages are not sent by threads.
The usage is as follows:
System. Threading. Timer threadtimer;
Public void threadmethod (object state)
{
// Use proxy
String text = "subthread execution, thread ID:" + system. Threading. thread. currentthread. managedthreadid. tostring () + "\ r \ n ";
Settextcallback d = new settextcallback (settext );
This. Invoke (D, new object [] {text });
I ++;
}
Private void form1_load (Object sender, eventargs E)
{
Threadtimer = new system. Threading. Timer (new system. Threading. timercallback (threadmethod), null,-1,-1 );
}
Pause code:
Threadtimer. Change (-1,-1 );
The experiment works in the same way as the server-based timer (system. Timers. Timer,
Of course, the specific usage method and principle are different. The most important thing is that this method uses the proxy method instead of the event method, and can be executed independently without relying on forms and components.
A table summarized by foreigners is listed below (the difference between the three methods ):
Feature description |
System. Timers. Timer |
System. Threading. Timer |
System. Windows. Forms. Timer |
Support for adding and removing listeners after the timer is instantiated. |
Yes |
No |
Yes |
Supports call backs on the user-interface thread |
Yes |
No |
Yes |
Callback from threads obtained from the thread pool |
Yes |
Yes |
No |
Supports drag-and-drop in the Windows Forms designer |
Yes |
No |
Yes |
Suitable for running in a server multi-threaded Environment |
Yes |
Yes |
No |
Provided des support for passing arbitrary State from the timer initialization to the callback. |
No |
Yes |
No |
Implements idisposable |
Yes |
Yes |
Yes |
Supports one-off callbacks as well as periodic repeating callbacks |
Yes |
Yes |
Yes |
Accessible implements SS application domain boundaries |
Yes |
Yes |
Yes |
Supports icomponent-hostable in an icontainer |
Yes |
No |
Yes |