3

La raison pour laquelle je demande est parce que la collection HttpContext.Current.Items semble être un bon endroit pour mettre IDisposable objets tels qu'un DataContext de sorte qu'un référentiel puisse y accéder de manière transparente sans avoir à injecter des dépendances liées à une technologie ORM spécifique dans le Dépôt. Cela permettrait également au référentiel de décider s'il doit ou non s'engager dans un UnitOfWork ou assumer la responsabilité supplémentaire de la persistance de tout changement.Le HttpContext.Current est-il éliminé même si une exception est levée?

Par exemple:

Le Page:

protected void Page_Load(...) 
{ 
    Items[KeyValueFromConfigurationFile] = new DataContext(); 
    var repo = new Repository(); 
    var rootEntity = repo.GetById(1); 
} 

Le dépôt:

public virtual TEntity GetById(int id) 
{ 
    var ctx = HttpContext.Current.Items[KeyValueFromConfigurationFile] as DataContext; 
    return ctx.TEntities.SingleOrDefault(p => p.Id == id); 
} 

Bien sûr, je vérifierais pour nulls et effectuer les étapes nécessaires pour obtenir un DataContext si elle n'était pas disponible dans la collection HttpContext.Current.Items.

Donc, retour à ma question d'origine donnée le code ci-dessus: Est-ce que le HttpContext.Current sera-t-il disposé avec l'un des objets contenus dans sa collection d'articles même si une exception est levée?

Répondre

13

Les objets contenus dans HttpContext.Current.Items ne seront pas automatiquement éliminés. Vous auriez besoin de gérer cela vous-même. Vous pouvez le faire dans le global.asax Application_EndRequest:

  foreach (var item in HttpContext.Current.Items.Values) 
      { 
       var disposableItem = item as IDisposable; 

       if (disposableItem != null) 
       { 
        disposableItem.Dispose(); 
       } 
      } 
+1

Merci, cela fonctionne. Une chose que les gens devraient noter est la fréquence à laquelle EndRequest est déclenché. Dans ce fil http://www.mojoportal.com/Forums/Thread.aspx?pageid=5&t=1558~-1. Le serveur Web Visual Studio déclenche cet événement pour toutes les demandes HTTP (y compris les images, css, etc), tandis que IIS se déclenche uniquement pendant les pages gérées .NET. Gardez cela à l'esprit si vous déboguez dans VS Web Server et que vous voyez l'événement se déclencher encore et encore. –

+0

'foreach (var v dans HttpContext.Current.Items.Values.OfType ()) v.Dispose();' – Denis

2

Je ne pensais pas qu'il y avait un problème avec le dernier message fournissant une solution parce que la collection sous-jacente n'est pas modifiée, ce qui ne peut se faire pendant qu'il est étant énuméré, mais j'ai récemment rencontré des erreurs sporadiques avec ce code. Nous voyions l'erreur 'La collection a été modifiée; l'opération d'énumération ne peut pas exécuter » lorsque OnEndRequest a tiré et exécuté la boucle ci-dessous:

 foreach (var item in HttpContext.Current.Items.Values) 
     { 
      var disposableItem = item as IDisposable; 

      if (disposableItem != null) 
      { 
       disposableItem.Dispose(); 
      } 
     } 

Donc, apparemment disposer les éléments de HttpContext actuels tout en réitérant la collection avec une boucle foreach peut également poser un problème. Il y a plusieurs façons de contourner cela, mais j'ai choisi de le faire de cette façon:

 int size = HttpContext.Current.Items.Count; 
     if (size > 0) 
     { 
      var keys = new object[size]; 
      HttpContext.Current.Items.Keys.CopyTo(keys, 0); 

      for (int i = 0; i < size; i++) 
      { 
       var obj = HttpContext.Current.Items[keys[i]] as IDisposable; 
       if (obj != null) 
        obj.Dispose(); 
      } 
     } 
+0

Ceci est juste, en quelque sorte la collection est modifiée et je ne suis pas sûr de la raison. Normalement, l'appel de disposition ne devrait pas affecter la collection. Peut-être que d'autres threads modifient la collection en même temps (Application_EndRequest se déclenche sur un thread différent de Application_BeginRequest et se trouve après/en même temps que le moment où la réponse est envoyée au client) – Cosmin

Questions connexes