How is a C # timer object defined when elapsed time has occurred?

How does a C # timer object determine when an elapsed time period has occurred?

I wonder if it is just loops or more intelligent than this one.

Also, it would be nice to know where to find the C # source code to view.

+4
source share
2 answers

There are at least two classes in .NET BCL that provide timers:

However, the second class is implemented using the first. The first class uses some kind of Win32 own timer, while Hans Passant provided more information about the mechanism used. In the BCL source code, a timer is implemented using an inner class called TimerQueue . The implementation of the TimerQueue class has the following comment:

TimerQueue maintains a list of active timers in this AppDomain. We use one built-in timer provided by VM to schedule all managed timers in AppDomain.

So basically AppDomain has one time source implemented using unmanaged code. See Hans Passant Response for more information.


Also, it would be nice to know where to find the C # source code to view.

I am using JetBrains dotPeek . It can be configured to receive source files from Microsoft, if they exist. Just download the version of .NET you want to learn, press Ctrl + T , type "Timer", select the class you want, and load the source, if it exists. Otherwise, you will see a decompiled version (depending on your configuration).

Note that this tool will allow you to decompile managed code and fully understand the implementation of timers in .NET. You will need to look further into unmanaged code.

+4
source

The CLR creates a dedicated thread that processes all the timer objects that you create in your application and fires a past event handler and a callback handler. You can see that it is used with a debugger. Start with an application in console mode that looks like this:

 using System; using System.Timers; class Program { static void Main(string[] args) { var t = Timer(); t.Elapsed += ElapsedEventHandler((s, e) => { }); t.Start(); } } 

Project + Properties, tab "Debugging", check the option "Enable custom code debugging" (the so-called unmanaged code). Tools + Options, Debugging, Symbols and make sure Symbol Server is turned on. Start debugging by pressing F11.

Now use Debug + Windows + Threads. You will see 4 threads. Your main thread, finalizer thread, debug thread, and downstream thread. Continue the step until you complete the call to the t.Start () method. Note that a new stream has now been added. The name is "ThreadPoolMgr :: TimerThreadStart". Double-click it and look at the Call Stack window. You will see:

 ntdll.dll!_NtDelayExecution@8 () + 0x15 bytes ntdll.dll!_NtDelayExecution@8 () + 0x15 bytes KernelBase.dll!_SleepEx@8 () + 0x39 bytes clr.dll!ThreadpoolMgr::TimerThreadFire() + 0x3e bytes clr.dll!ThreadpoolMgr::TimerThreadStart() + 0x6a bytes kernel32.dll!@BaseThreadInitThunk @12() + 0x12 bytes ntdll.dll!___RtlUserThreadStart@8 () + 0x27 bytes ntdll.dll!__RtlUserThreadStart@8 () + 0x1b bytes 

The important bits here are the TimerThreadStart () function, which is the starting point for the thread that the CLR started. And call SleepEx () so that this thread sleeps until the next timer. This stack trace was for .NET 4.5; it was the same as with .NET 2.0. For what source code is available, you can look in the source code SSCLI20, which you can download here . Searching for this code will lead you to the clr / src / vm / win32threadpool.cpp source file. Look at this to see what happens.

I'll just talk about it. The synchronization source is the GetTickCount () api function, the same as the one used by Environment.TickCount. The FireTimers () function sorts which of the active timers should be first. The SleepEx () function is similar to the Thread.Sleep () function, except that it is a warning function. It can be interrupted before sleep is completed using APC (asynchronous procedure call). You see that the QueueUserAPC () function is used in the same file when the thread must end because the program is shutting down and when the timer is added or changed, so you need to calculate a new dream.

+7
source

Source: https://habr.com/ru/post/1442780/


All Articles