ASP MVC: kiedy jest wywoływana metoda Icontroller Dispose ()?

Przechodzę przez dużą refaktoryzację / szybką zmianę jednej z moich większych aplikacji MVC. Został wdrożony do produkcji już od kilku miesięcy, a ja zaczynałem dostawać przerwy w oczekiwaniu na połączenia w puli połączeń. Wyśledziłem problem do połączenia nie są usuwane prawidłowo.

W związku z tym, od tego czasu dokonałem tej zmiany w moim kontrolerze bazowym:

public class MyBaseController : Controller
{
    private ConfigurationManager configManager;  // Manages the data context.

    public MyBaseController()
    {
         configManager = new ConfigurationManager();
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            if (this.configManager != null)
            {
                this.configManager.Dispose();
                this.configManager = null;
            }
        }

        base.Dispose(disposing);
    }
}
Mam dwa pytania:]}
  1. czy przedstawiam wyścig warunek? Ponieważ configManager zarządza DataContext, który wyświetla IQueryable<> parametry do widoki, muszę się upewnić, że Dispose() nie będą wywoływane na kontrolerze przed zakończeniem renderowania widoku.
  2. czy Framework MVC wywołuje Dispose() na kontrolerze przed lub po renderowaniu widoku? Lub, czy Framework MVC pozostawia to do GarbageCollector?
Author: Amirhossein Mehrvarzi, 2009-09-04

2 answers

Dispose jest wywoływany po wyrenderowaniu widoku, Zawsze .

Widok jest renderowany w wywołaniu ActionResult.ExecuteResult. To jest wywołane (pośrednio) przez ControllerActionInvoker.InvokeAction, Które z kolei jest wywołane przez ControllerBase.ExecuteCore.

Ponieważ kontroler znajduje się w stosie wywołań podczas renderowania widoku, nie można go wtedy usunąć.

 62
Author: Craig Stuntz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-25 15:08:35

Aby rozwinąć odpowiedź Craiga Stuntza :

ControllerFactory obsługuje, gdy kontroler jest usuwany. Podczas implementacji interfejsu IControllerFactory jedną z metod, które należy zaimplementować, jest ReleaseController.

Nie jestem pewien, jakiego ControllerFactory używasz, czy wywróciłeś swój własny, ale w Reflector patrząc na DefaultControllerFactory, metoda ReleaseController jest zaimplementowana w następujący sposób:

public virtual void ReleaseController(IController controller)
{
    IDisposable disposable = controller as IDisposable;
    if (disposable != null)
    {
        disposable.Dispose();
    }
}

IController reference jest przekazywane, jeżeli ten kontroler implementuje IDisposable, wtedy jest wywoływana metoda Disposable. Tak więc, jeśli masz coś, co musisz usunąć po zakończeniu żądania, czyli po renderowaniu widoku. Dziedzicz z IDisposable i umieść swoją logikę w metodzie Disposable, aby zwolnić wszelkie zasoby.

Metoda ReleaseController jest wywoływana przez System.Www.Mvc.MvcHandler, który obsługuje żądanie i implementuje IHttpHandler. ProcessRequest pobiera HttpContext podane do niego i rozpoczyna proces znalezienia kontrolera do obsługi żądania, poprzez wywołanie do zaimplementowanego ControllerFactory. Jeśli spojrzysz w metodzie ProcessRequest zobaczysz finally block, który wywołuje ReleaseController Controllera Controllerfactory. Jest to wywołane tylko wtedy, gdy kontroler zwrócił wynik ViewResult.

 34
Author: Dale Ragan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:30