82 votes

ASP net MVC: Quand est IController Dispose() appelé?

Je vais à travers un gros refactoring / vitesse de peaufinage de l'une de mes plus grandes MVC apps. Il a été déployée en production depuis quelques mois maintenant, et je commençais à trouver que délais d'attente pour les connexions dans le pool de connexion. J'ai suivi l'émission vers le bas pour les connexions n'obtenant pas éliminés correctement.

À la lumière de ce que, depuis, j'ai fait ce changement à mon contrôleur de base:

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

Simple de disposer le code. Maintenant, j'ai juste une question:

Suis-je l'introduction d'une condition de concurrence?

Depuis l' configManager gère l' DataContext qui expose IQueryable<> paramètres de la vue, j'ai besoin de assurez-vous que Dispose() ne sera pas appelé sur le contrôleur avant le point de vue des finitions au rendu.

Donc, la vraie question est:

Le framework MVC appel Dispose() sur le Contrôleur avant ou après le point de vue est rendue? Ou, le framework MVC laisse la place à la GarbageCollector?

70voto

Craig Stuntz Points 95965

Dispose est appelé après le point de vue est rendu, toujours.

La vue est rendue dans l'appel à ActionResult.ExecuteResult. Qui est (indirectement) par ControllerActionInvoker.InvokeAction, qui est appelé à son tour par ControllerBase.ExecuteCore.

Depuis le contrôleur est dans la pile d'appel lorsque la vue est rendue, elle ne peut pas être éliminés ensuite.

37voto

Dale Ragan Points 14495

Juste pour élargir sur Craig Stuntz Réponse:

Le ControllerFactory poignées quand un Contrôleur est éliminé. Lors de la mise en œuvre de la IControllerFactory interface, l'une des méthodes qui doivent être mises en œuvre est ReleaseController.

Je ne suis pas sûr de ce que ControllerFactory que vous utilisez, si vous avez obtenu votre propre, mais dans un Réflecteur en regardant les DefaultControllerFactory, le ReleaseController méthode est implémentée comme suit:

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

Un IController de référence est passé, si le contrôleur met en œuvre IDisposable, alors que les contrôleurs disposent de la méthode est appelée. Donc, si vous avez quelque chose que vous avez besoin de l'élimination après la demande n'est pas terminée, ce qui est après le point de vue est rendu. Hériter hors de IDisposable et de mettre votre logique dans la méthode dispose pour libérer les ressources.

Le ReleaseController méthode est appelée par le Système.Web.Mvc.MvcHandler qui traite la demande et il met en œuvre IHttpHandler. Le ProcessRequest prend la HttpContext donné à lui et commence le processus de trouver le contrôleur pour gérer la demande, en appelant à la mise en œuvre ControllerFactory. Si vous regardez dans la méthode ProcessRequest vous verrez le bloc finally qui appelle à la ControllerFactory de ReleaseController. Ce n'est appelée que lorsque le Contrôleur a renvoyé un ViewResult.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X