События MVC перекрываются? - PullRequest
       38

События MVC перекрываются?

0 голосов
/ 29 августа 2018

В какой момент времени 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;
    ...

Как он узнает, когда завершился предыдущий обработчик (предыдущего события)? Вызывается ли обработчики синхронно, чтобы быть готовыми один за другим? Вот один пример:

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

Обычно выполнение обработчиков событий, вызываемых один за другим, перекрывается. Это не так. Почему?

1 Ответ

0 голосов
/ 29 августа 2018

Я нашел ответ в другом посте: синхронны ли события 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
...