EFL is event-driven. This means that execution usually takes place within an internal EFL *Main Loop*. The application receives notifications through function callbacks. These can apply to virtually any event which occurs on a computer.
Events play a central role in EFL. In this guide, you'll learn more about the required methods to handle them.
| ![NOTE](/_media/note-important.png) | **Some C# classes are currently in BETA state**<br>They should only be used for experimenting and **NOT** for any product development.<br>These classes are marked as **BETA** in the reference documentation.<br>The source code for the tutorials is subject to change in the future. | ![NOTE](/_media/note-important.png) |
All EFL objects can emit events. You can discover more about them in the **Events** section of their respective [API Reference documentation](/develop/api/) (only in C, C# *coming soon*).
Substitute *object* with any EFL object and *event* with the identifier of the event (such as ``PollHighEvt`` or ``TickEvt``). Set *callback* to the method to be invoked when the event occurs.
*sender* is the object that emitted the event and *e* contains any additional information that the event sent. Events emitting additional information require that you use their own *EventArgs* class, for example, `Efl.Input.InterfaceKeyDownEvt_Args` when connecting to the `Efl.Input.Interface.KeyDownEvt` event.
Note that in order to unregister the callback you have to provide the callback method again. This is because you can register different callback methods for the same event.
Remember that ALL events emitting from a object are stopped if it's frozen, except for hot events. If you need to stop individual events you can unregister their callback temporarily and then re-register later.
Below is the `core_event.cs` example taken from [the examples repository](https://git.enlightenment.org/enlightenment/examples/src/branch/master/reference/csharp/core/src/core_event.cs):
A handler is connected to the `PollHighEvt` event of the application's main loop, which triggers continuously, at an undefined frequency of several shots per second (See the [Main Loop Programming Guide](main-loop.md)). At every shot, a line is printed on the console.
At the same time, a timer is instantiated, firing every 100ms, which does a different thing at every shot:
* First it freezes (pauses) all main loop events (except hot ones).
* Then it thaws (resumes) all main loop events.
* Finally, it quits the application.
When you run the application, it should produce something like this on the console:
```
Waiting for Timer to call back...
Poll from Mainloop
Poll from Mainloop
Poll from Mainloop
Poll from Mainloop
Poll from Mainloop
Poll from Mainloop
Tick 0 from Timer: Freezing Mainloop events
Tick 1 from Timer: Thawing Mainloop events
Poll from Mainloop
Poll from Mainloop
Poll from Mainloop
Poll from Mainloop
Poll from Mainloop
Poll from Mainloop
Tick 2 from Timer: Quitting
```
As you can see, the line `Poll from Mainloop` is printed continuously except in the period between Tick 0 and Tick 1 of the Timer, where main loop events are frozen.
The exact amount of `Poll from Mainloop` messages you get depends on the frequency of the `PollHighEvt` event, which is chosen by EFL. The important thing is that there should be no such messages in between timer ticks 0 and 1, since main loop events are frozen.