245 votes

Pourquoi utiliser try {} finally {} avec un bloc try vide ?

J'ai remarqué dans System.Threading.TimerBase.Dispose() que la méthode contient un bloc try{} finally{} mais le bloc try{} est vide.

Y a-t-il une utilité à utiliser try{} finally{} avec un bloc try vide ?

http://labs.developerfusion.co.uk/SourceViewer/browse.aspx?assembly=SSCLI&namespace=System.Threading&type=TimerBase

[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
internal bool Dispose(WaitHandle notifyObject)
{
    bool status = false;
    bool bLockTaken = false;
    RuntimeHelpers.PrepareConstrainedRegions();
    try {
    }
    finally {
        do {
            if (Interlocked.CompareExchange(ref m_lock, 1, 0) == 0) {
                bLockTaken = true;
                try {
                    status = DeleteTimerNative(notifyObject.SafeWaitHandle);
                }
                finally {
                    m_lock = 0;
                }
            }
            Thread.SpinWait(1);
            // yield to processor
        }
        while (!bLockTaken);
        GC.SuppressFinalize(this);
    }

    return status;
}

0 votes

System.Diagnostics.Process vers la ligne 2144 également: referencesource.microsoft.com/#System/services/monitoring/…

176voto

danben Points 35312

De http://blog.somecreativity.com/2008/04/10/the-empty-try-block-mystery/:

Cette méthodologie protège contre un appel de Thread.Abort interrompant le traitement. La page MSDN de Thread.Abort indique que "Les blocs finally non exécutés sont exécutés avant que le thread ne soit avorté". Ainsi, pour garantir que votre traitement se termine même si votre thread est interrompu en plein milieu par quelqu'un appelant Abort sur votre thread, vous pouvez placer tout votre code dans le bloc finally (l'alternative est d'écrire du code dans le bloc "catch" pour déterminer où vous étiez avant que le "try" ne soit interrompu par Abort et continuer à partir de là si vous le souhaitez).

6 votes

Pourquoi ne pas utiliser msdn.microsoft.com/en-us/library/…?

15 votes

Parce que ce n'était pas disponible avant .NET 2.0

6 votes

@RobFonseca-Ensor : Parce que Thread.BeginCriticalRegion() ne empêche pas un thread d'être annulé, mais indique plutôt au runtime que si un thread est annulé, alors l'état global est corrompu et que le domaine d'application entier est voué à une mort miséricordieuse.

65voto

Anton Gogolev Points 59794

Ceci est pour se protéger contre l'interruption de processus par Thread.Abort. La documentation de cette méthode indique que :

Les blocs finally non exécutés sont exécutés avant que le thread soit interrompu.

Cela est dû au fait que pour récupérer avec succès d'une erreur, votre code devra effectuer un nettoyage. Comme C# n'a pas de destructeurs de style C++, les blocs finally et using sont les seuls moyens fiables de garantir que ce nettoyage est effectué de manière fiable. Rappelez-vous que le bloc using se transforme ainsi par le compilateur :

try {
    ...
}
finally {
    if(obj != null)
        ((IDisposable)obj).Dispose();
}

Dans .NET 1.x, il y avait une chance que le bloc finally soit interrompu. Ce comportement a été modifié dans .NET 2.0.

De plus, les blocs try vides ne sont jamais optimisés par le compilateur.

0 votes

Merci pour l'aperçu sur l'utilisation du bloc.

0 votes

@Anton Je comprends que l'utilisation using est une bonne pratique. Mais dans certains cas d'utilisation de faux objets, il est parfois nécessaire d'implémenter une classe enveloppe et l'objet jetable devient une variable de classe privée. Si nous rendons cette enveloppe jetable, est-ce que le GC gère automatiquement la suppression de la variable de classe privée?

0 votes

@Ozkan le GC ne libère rien automatiquement. Vous devriez implémenter une méthode finalizer, appelant généralement un Dispose(false);. docs.microsoft.com/en-us/dotnet/standard/garbage-collection/‌​…

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