1

MvcApplication 在哪个时间点调用 HttpAplications 事件,例如:

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

它如何知道(上一个事件的)上一个 Handler 什么时候完成?是同步调用的 Handler 一个接一个准备好了吗?这里有一个例子:

    // 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

通常,一个接一个地调用的事件处理程序的执行会重叠。这些没有。为什么?

4

1 回答 1

2

我在另一篇文章中找到了答案:C# 事件是同步的吗?

它表示事件或组合的支持委托是通过 Invoke 方法而不是 InvokeAsync 方法调用的,这意味着默认情况下,.Net 事件是同步调用的。

有一个例外:

如果事件处理程序都是同步实现的,那么引发事件确实会阻塞线程。

这意味着内部 HttpApplication 一个接一个地调用附加的处理程序,然后如果所有事件都是同步的,则继续执行下一个事件。这使得在一个处理程序中所做的更改可以在稍后添加到事件的另一个处理程序中覆盖。

事件处理程序按照订阅事件的顺序依次执行。

因为我知道重要的 MVC 事件处理程序是同步的,所以这应该不是问题。但是,只要一个附加的事件处理程序是 aysnc,组合的委托(支持事件委托)就会异步运行。

  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
于 2018-08-29T16:35:28.127 回答