[asp.net-mvc] ASP MVC : IController Dispose ()는 언제 호출됩니까?

더 큰 MVC 앱 중 하나를 크게 리팩토링 / 속도 조정 중입니다. 이제 몇 달 동안 프로덕션에 배포되었으며 연결 풀에서 연결을 기다리는 시간 초과가 발생하기 시작했습니다. 제대로 처리되지 않는 연결까지 문제를 추적했습니다.

이를 고려하여 이후 기본 컨트롤러를 다음과 같이 변경했습니다.

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);
    }
}

이제 두 가지 질문이 있습니다.

  1. 경쟁 조건을 도입하고 있습니까? 뷰에 매개 변수를 노출 하는을 configManager관리 하므로 뷰가 렌더링을 완료하기 전에 컨트롤러에서 호출되지 않는지 확인해야합니다 .DataContextIQueryable<>Dispose()
  2. Dispose()뷰가 렌더링되기 전이나 후에 MVC 프레임 워크 가 컨트롤러에서 호출 합니까? 아니면 MVC 프레임 워크가이를 GarbageCollector에 맡깁니까?



답변

Dispose는 뷰가 렌더링 된 후 항상 호출됩니다 .

뷰는에 대한 호출에서 렌더링됩니다 ActionResult.ExecuteResult. 이것은 (간접적으로)에 의해 호출되며 ControllerActionInvoker.InvokeAction, 차례로에 의해 호출됩니다 ControllerBase.ExecuteCore.

뷰가 렌더링 될 때 컨트롤러가 호출 스택에 있기 때문에 폐기 할 수 없습니다.


답변

Craig Stuntz의 답변 을 확장하려면 :

ControllerFactory는 Controller가 삭제 될 때 처리합니다. IControllerFactory 인터페이스를 구현할 때 구현해야하는 메서드 중 하나는 ReleaseController입니다.

자신의 롤링 여부에 관계없이 어떤 ControllerFactory를 사용하고 있는지 확실하지 않지만 Reflector에서 DefaultControllerFactory를 보면 ReleaseController 메서드가 다음과 같이 구현됩니다.

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

해당 컨트롤러가 IDisposable을 구현하는 경우 IController 참조가 전달되면 해당 컨트롤러의 Dispose 메서드가 호출됩니다. 따라서 요청이 완료된 후, 즉 뷰가 렌더링 된 후 처리해야하는 항목이있는 경우. IDisposable을 상속하고 Dispose 메서드에 논리를 넣어 리소스를 해제합니다.

ReleaseController 메서드는 요청을 처리하고 IHttpHandler를 구현하는 System.Web.Mvc.MvcHandler에 의해 호출됩니다. ProcessRequest는 주어진 HttpContext를 받아서 구현 된 ControllerFactory를 호출하여 요청을 처리 할 컨트롤러를 찾는 프로세스를 시작합니다. ProcessRequest 메소드를 살펴보면 ControllerFactory의 ReleaseController를 호출하는 finally 블록을 볼 수 있습니다. Controller가 ViewResult를 반환 한 경우에만 호출됩니다.


답변