The opposite to event-driven is polling architecture. Though both actually respond to an event in order to handle it, "event-driven" usually refers to the apparently asynchronous way the handler is called and to an encapsulation of the handler in the code, usually in the form of a subprogram.
Event-driven programming does not necessarily imply concurrent programming. In fact, very often events are handled synchronously on the context of a single task. Furthermore event-driven architectures were used in the past as a substitute for proper multitasking support, for example in Windows and MS-DOS prior to 95 and NT.
In a truly multitasking environment event-driven programming is exposed to serious problems, especially to deadlocks. To other problems belong:
- unpredictable, often poor, behavior with respect to the response time and stack memory use;
- complexity of the arguments and results passing, especially between multiple tasks;
- handlers composition. Though some event-driven systems provide tools for routing, filtering events, chaining handlers etc;
- low abstraction level. (This is usually alleviate when an even-driven architecture is wrapped into an OO model).
Event-driven programming is quite popular in GUI design. Many GUI widget libraries have event-driven architecture. It is also used in database programming in the form of triggers. In systems programming hardware communication is predominantly event-driven per hardware nature.