Question

J'ai un service WCF auto-hébergé et je vais avoir le problème suivant: 15 minutes après la création de l'instance du service TryEnter appelle des méthodes de contrat d'opération retour constamment faux, mais le TryEnter appelle la fonction principale, qui utilise également synchronisation via classe Monitor, return true.

Voici la description de mon application et le bug: Je développe un service WCF auto-hébergé dans Visual Studio 2008 (C #) dans Windows XP SP2. L'instance ServiceHost de l'hôte est créé au début de la fonction principale. La fonction principale exécute une boucle while (true) au cours de laquelle il effectue des lectures périodiques, l'écriture, l'entretien, etc. Il y a une collection statique d'objets (qui peuvent être ajoutés ou supprimés au fil du temps), qui agissent comme des conteneurs pour threads de travail. Certains de ces fils font un travail périodique demandé par la fonction principale, tandis que d'autres effectuent la lecture à la demande et de l'écriture à un périphérique distant. verrouillage de synchronisation se fait sur ces objets à l'aide classe Monitor (méthodes TryEnter et sortie). Ces objets sont également accessibles par les méthodes de contrat de services (services) en utilisant les mêmes fonctions. La synchronisation est effectuée entre la fonction principale et les méthodes de service. Lorsque l'instance du service est créé, il fonctionne avec des performances conçu pour exactement 15 minutes, après quoi tous les TryEnter (obj, délai d'attente) fait appel du service retourne faux après le délai spécifié expire. Cela ne touche pas les appels TryEnter effectués dans la fonction principale à-dire qu'ils reviennent toujours vrai. J'ai essayé de changer les paramètres de InstanceContextMode, ConcurrencyMode, couplé avec des attributs d'étranglement de service maxConcurrentCalls = "1"; MaxConcurrentSessions = "5" et chaque configuration a le même effet. Le service devient réactif à nouveau lorsque je redémarre l'application hôte, mais pas quand je force fermer et rouvrir l'hôte lorsque l'application est en cours d'exécution (l'instance de service reste dans la mémoire). Il est pas un cas de service étant disponible, comme dans l'appel ne fait son chemin à l'instance de service. La méthode est appelée, son exécution vient à l'appel TryEnter qui précède la section critique de la méthode et TryEnter juste retourne false après le délai d'attente (15 secondes). J'ai vérifié et revérifié les appariements de TryEnter et de sortie - les méthodes libèrent toujours le verrou lorsque la section critique se termine. D'autres opérations contractuelles qui n'utilisent pas le verrouillage ou les objets en question le travail bien même après la période de 15 minutes est terminée.

Merci tout à l'avance. Joyeuses fêtes!

Était-ce utile?

La solution

Monitor est rentrante, il sonne comme le fil avec votre méthode de Main n'a pas réussi à libérer un verrou. Alors, quand il demande le verrou (TryEnter) il obtient le verrou (incrémenter le compteur par autre un).

Toutes les autres discussions seront refusées. Vous aurez besoin de déboguer où se fait prendre et a tenu le verrou.

  

J'ai vérifié et revérifié les appariements de TryEnter et de sortie - les méthodes libèrent toujours le verrouillage lorsque les extrémités de section critique

désolé, mais je pense que vous allez vérification des aigus. En particulier, contrairement à lock, TryEnter aura pas la gestion des exceptions spéciales. Votre code devrait ressembler à:

if(Monitor.TryEnter(lockObj, timeout)) {
    try {
        ...
    } finally {
        Monitor.Exit(lockObj);
    }
}

En outre - faire en sorte que vous ne reasign votre lockObj dans le code, car cela ne se déverrouille pas l'objet correct

.

(ou similaire en utilisant un drapeau, en particulier dans .NET 4.0 où il y a des nouvelles pour Enter surcharges etc)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top