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:]}
-
czy przedstawiam wyścig warunek? Ponieważ
configManager
zarządzaDataContext
, który wyświetlaIQueryable<>
parametry do widoki, muszę się upewnić, żeDispose()
nie będą wywoływane na kontrolerze przed zakończeniem renderowania widoku. - czy Framework MVC wywołuje
Dispose()
na kontrolerze przed lub po renderowaniu widoku? Lub, czy Framework MVC pozostawia to do GarbageCollector?
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ąć.
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.
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