Events are synchronous. This is why the event lifecycle works the way it does. Inits happen before loads, loads happen before renders etc.
If no handler is specified for an event, the cycle just blazes through. If more than one handler is specified, they will be called in order and one can't continue until the other is completely finished.
The delegates subscribed to the event are invoked synchronously in the order they were added. If one of the delegates throws an exception, the ones following will not be called.
I too was curious about the internal mechanism of event and its related operations. So I wrote a simple program and used ildasm to poke around its implementation.
public class Foo
{
// cool, it can return a value! which value it returns if there're multiple
// subscribers? answer (by trying): the last subscriber.
public event Func<int, string> OnCall;
private int val = 1;
public void Do()
{
if (OnCall != null)
{
var res = OnCall(val++);
Console.WriteLine($"publisher got back a {res}");
}
}
}
public class Program
{
static void Main(string[] args)
{
var foo = new Foo();
foo.OnCall += i =>
{
Console.WriteLine($"sub2: I've got a {i}");
return "sub2";
};
foo.OnCall += i =>
{
Console.WriteLine($"sub1: I've got a {i}");
return "sub1";
};
foo.Do();
foo.Do();
}
}