2 votes

Accès à l'avertissement de fermeture éliminé à l'aide de la politique de réessai de gestion des défaillances transitoires d'Azure

Nous avons un rôle de travailleur qui traite les enregistrements et envoie des messages au bus de service Azure si nécessaire en fonction des résultats de la requête, il s'agit essentiellement d'un service de traitement de file d'attente. Dans le cadre des meilleures pratiques d'utilisation de SQL Azure, nous avons enveloppé toutes nos instructions de requête avec une politique de réessai (qui détecte les erreurs transitoires et réessaie en fonction de la politique définie). Notez que nous envoyons le message à partir de l'instruction using, de sorte qu'il n'y a pas de "fuite" de la variable db.

À l'intérieur de notre déclaration d'utilisation, ReSharper affiche l'avertissement 'Access to Disposed Closure', probablement parce que nous passons notre DataContext en tant que paramètre func de la politique de réessai.

Ma question est la suivante : ai-je raison de supposer que ReSharper ne détecte pas correctement ce modèle ou existe-t-il d'autres méthodes pour écrire ces fonctions afin d'éviter l'avertissement ci-dessus ?

Le code

La variable db dans retryPolicy.ExecuteAction est ce qui est signalé.

using (var db = new MyEntities())
{
   var thingsToUpdate = retryPolicy.ExecuteAction(() => db.QueueTable.Where(x => x.UpdateType == "UpdateType" && x.DueNext < DateTime.UtcNow).Take(30).ToList());
   if (!thingsToUpdate.Any())
   {
      return;
   }
   while (thingsToUpdate.Any())
   {
      var message = new ServiceMessage{
                            Type = "UpdateType",
                            Requests = thingsToUpdate.Select(x => new ServiceMessageRequest
                                {
                                    LastRan = x.LastRan,
                                    ParentItemId = x.ThingId,
                                    OwnerId = x.Thing.ForiegnKeyid
                                }).ToList()
                        };
      SendMessage("UpdateType", message);
      foreach (var thing in thingsToUpdate )
      {
          thing.LastRan = DateTime.UtcNow;
          thing.DueNext = DateTime.UtcNow.AddMinutes(10);
      }
      retryPolicy.ExecuteAction(() => db.SaveChanges());
      thingsToUpdate = db.QueueTable.Where(x => x.UpdateType == "UpdateType" && x.DueNext < DateTime.UtcNow).Take(30).ToList());
     }
}

Informations complémentaires

J'ai également posté ce message sur les forums de ReSharper pour une audience plus large et ce problème particulier y a été abordé de manière un peu plus détaillée. Pour la postérité, vous pouvez trouver le question ici.

4voto

Dmitry Osinovskiy Points 5420

Je suppose que votre ExecuteAction exécute votre lamdba immédiatement. Vous devriez alors annoter un paramètre lambda de votre méthode ExecuteAction avec l'attribut [InstantHandle] de ReSharper.

Par exemple :

public void ExecuteAction([InstantHandle] Action action)
{
  ...
}

Vous pouvez soit importer JetBrains.Annotations.dll pour obtenir cet attribut, soit copier tous les attributs dans votre projet. Plus d'informations sur le site de JetBrains aquí y aquí .

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