4

In all the books regarding C#/.NET that I have seen till now, when they talk about Events,
they talk about Creating and Consuming Events.

I am curious to understand a bit how it works behind our code - what is the mechanism that runs it.

I know a little bit from the fact that the Windows Message Loop is acting like a Queue for the events that are raised.
For example, WM_KEYDOWN, or WM_LBUTTONDOWN, etc..

But what happens for example, If I create a class that does not inherit class Control, and this class raises an event?
(which another class, which also does not inherit class Control, receives it)

Will the raised event go thru the message loop?
It sound not so logic..
(yet assume that the project is a Windows Forms project, just the 2 classes - the sender and the receiver are not GUI classes at all, but simple classes that you wrote)

Any explanation or link to an article about the mechanism behind our code will be highly appreciated.

spaceman
  • 1,061
  • 1
  • 11
  • 31
  • Related: http://stackoverflow.com/q/803242/578411 – rene Dec 27 '15 at 16:16
  • 1
    @rene I think that is related, not a duplicate. – Sweeper Dec 27 '15 at 16:20
  • Just slightly related, not more than that.. The guy there asks "What do event handlers do, why are they needed, and how do I to create one?" - which is not what I ask. I already know that part, and as said, all books answer that basic question.. – spaceman Dec 27 '15 at 16:22
  • Well, there's the obligatory [MSDN Tutorial](https://msdn.microsoft.com/library/aa645739.aspx). Basically, think of the event variable as something like a list of methods. Other objects can put methods into that list by "subscribing to an event": `eventObject.EventVariable += otherObject.SomeMethod;`. Then, when that specified event happens in `eventObject`, it goes through all the methods in that list and calls them all one by one. -- Btw. the book [CLR via C#](http://www.amazon.com/CLR-via-Edition-Developer-Reference/dp/0735667454) has in depth information about the inner workings of events. – Corak Dec 27 '15 at 16:22
  • Corak: I went over "CLR via C#" today, and the material he has about events is pretty much like other books: Creating, Consuming.. I exptected more info about the CLR there, but did not find any at all. It was exactly like the material in other books. – spaceman Dec 27 '15 at 16:26
  • It sounds like you expect some "magic" behind events. But there is none. Like I said, the event variable stores a list of methods (delegates) which other objects (or itself) can provide. And then if something in that eventObject happens that is classified as that event, all those methods in that list are called. Simple as that. Where do you think there is "more" happening? – Corak Dec 27 '15 at 16:43
  • Corak: regarding "Where do you think there is "more" happening?" - I gave an example the message loop.. – spaceman Dec 27 '15 at 16:45
  • Ah, okay. then as Rob wrote, those are two similar but different things. – Corak Dec 27 '15 at 16:49

1 Answers1

4

I hope I'm understanding your question correctly. I think we're talking about two things.

First - how events work in C# Second - how a WinForms application written in C# knows when you've clicked a button.

Events in C# are their own distinct thing. You can write a console app, create your own event, listen to it, fire it, respond to it, etc... and it all just works. You subscribe to an event by called Add() and you unsubscribe by calling Remove(). The event itself keeps track of what methods are listening to it and when it's raised, calls all of those methods.

Jon Skeet explains it much better: How do C# Events work behind the scenes?

But these events are just C# code. Related to, but distinct from the Win32 messages you're mentioning. In a Winforms application, when the user clicks a button, how does the application know about it? We can look using the debugger (turn off the 'My Code' https://msdn.microsoft.com/en-us/library/dn457346.aspx option) and set a breakpoint in the click event, you'll be able to see what is going on.

Callstack

So in Windows.Forms.Controls.ControlNativeWindow there is a WndProc method that takes in a System.Windows.Forms.Message m.

Right before that is a 'debuggableCallback' method. That mirrors what you'd expect from a Win32API app.

Source here: http://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/NativeWindow.cs,ad40308c5b6490dd

/// <include file='doc\NativeWindow.uex' path='docs/doc[@for="NativeWindow.DebuggableCallback"]/*' />
/// <devdoc>
///     Window message callback method. Control arrives here when a window
///     message is sent to this Window. This method packages the window message
///     in a Message object and invokes the wndProc() method. A WM_NCDESTROY
///     message automatically causes the releaseHandle() method to be called.
/// </devdoc>
/// <internalonly/>
private IntPtr DebuggableCallback(IntPtr hWnd, int msg, IntPtr wparam, IntPtr lparam) {

    // Note: if you change this code be sure to change the 
    // corresponding code in Callback above!

    Message m = Message.Create(hWnd, msg, wparam, lparam);

    try {
        if (weakThisPtr.IsAlive && weakThisPtr.Target != null) {
            WndProc(ref m);
        }
        else {
            DefWndProc(ref m);
        }
    }
    finally {
        if (msg == NativeMethods.WM_NCDESTROY) ReleaseHandle(false);
        if (msg == NativeMethods.WM_UIUNSUBCLASS) ReleaseHandle(true);
    }

    return m.Result;
}

So, ultimately, if you're running on Windows, it's driven by the same Win32 API messages you'd expect. It's just that the System.Windows.Forms classes are written to encapsulate most of it from us.

Community
  • 1
  • 1
Rob P.
  • 14,921
  • 14
  • 73
  • 109
  • Thank you Rob P., very nice. I hope someone can elaborate on what happens with events that are not UI events, that happen with classes that are not inheritors of `class Control`. Are WindowsMessages being used there too? or some other way? – spaceman Dec 27 '15 at 16:33
  • @spaceman Did you read Jon Skeet's article? If so, what aspects of your question remain unanswered? – Χpẘ Dec 27 '15 at 18:47
  • user2460798: Are you talking about this one? http://csharpindepth.com/Articles/Chapter2/Events.aspx If so, then yes. It explains everything from our side - the developers code side (delegates, etc), but not from the CLR's side.. which is what I ask about here – spaceman Dec 27 '15 at 18:55
  • For anyone interested in this subject, it seems that using Reflector on `System.Windows.Forms.Application.DoEvents()` can give more hints regarding what happens behind. But of course, it will not be easy to read.. – spaceman Dec 29 '15 at 14:14