asp.netasp.net-mvchttpapplication

Do MVC events overlap?


At which point and time does the MvcApplication call the HttpAplications events like:

    ...
    public event EventHandler PreSendRequestHeaders;
    public event EventHandler PostResolveRequestCache;
    public event EventHandler PreSendRequestContent;
    public event EventHandler PostMapRequestHandler;
    public event EventHandler PostLogRequest;
    public event EventHandler RequestCompleted;
    ...

How does it know when the previous Handler (of the previous event) has finished?Are the Handlers called synchronously to be ready one after another? Here one example:

    // gets called through HttpApplication.BeginRequest event
    protected void Application_BeginRequest() {
         Thread.Sleep(60000);
         // Waits very long
         Debug.WriteLine("begin");
    }

    // gets invoked after BeginRequest by the Event AuthenticateRequest
    // Event is used to attach Authentication related operations to it 
    protected void Application_AuthenticateRequest() {
         Debug.WriteLine("authentication in process");
    }


    // Output:
    // begin
    // authentication in process

Normally the excution of event handlers which are called one after another, would overlap. These do not. Why?


Solution

  • I found the answer in another post: are C# events synchronous?

    It says that an event or the combined backing delegate is called via the Invoke method rather than the InvokeAsync method which means that by default .Net events are called synchronously.

    There is one exception:

    Raising an event does block the thread if the event handlers are all implemented synchronously.

    This means that the inner HttpApplication is calling the attached handlers one after another and then goes on to the next event if all events are synchronous. This makes the changes made in one handler overridable in another handler which is added later to the event.

    The event handlers are executed sequentially, one after another, in the order they are subscribed to the event.

    Since I know the important MVC event handlers are synchronous this should not be a problem. But as soon as one attached event handler is aysnc the combined delegate (backing event delegate) is run async.

      class Program
    {
        static void Main(string[] args)
        {
            var foo = new Foo();
            foo.OnWork += async (e, v) =>
            {
               await Task.Run(() =>
                {
                    Thread.Sleep(1000);
                    Console.WriteLine(v);
                });
            };
            foo.OnWork += (e, v) =>
            {
                Console.WriteLine("2." + v);
            };
    
            foo.DoWork();
            foo.DoWork();
    
            Console.ReadLine();
        }
    }
    
    public class Foo
    {
        public event EventHandler<int> OnWork;
    
        private int val = 1;
    
        public void DoWork()
        {
            OnWork?.Invoke(this, val++);
        }
    }
    
    // Output:
    // 2.1
    // 2.2
    // 1
    // 2
    
    // Sometimes 1 and 2 are reversed because they are running in different Threads