Les méthodes statiques sont-elles sûres

J’ai une classe de timer statique qui sera appelée par TOUTES les pages Web pour calculer la durée de construction de chaque page.

Ma question est la suivante: les classes statiques sont-elles sécuritaires? Dans mon exemple, les utilisateurs concurrents causeront-ils un problème avec mes heures de début et de fin? Par exemple, un thread différent écrase mes valeurs de départ et d’arrêt.

public static class Timer { private static DateTime _startTime; private static DateTime _stopTime; ///  /// Gets the amount of time taken in milliseconds ///  ///  public static decimal Duration() { TimeSpan duration = _stopTime - _startTime; return duration.Milliseconds; } public static void Start() { _startTime = DateTime.Now; } public static void Stop() { _stopTime = DateTime.Now; } } 

Cette classe devrait-elle être une classe non statique?

(Cette classe sera appelée à partir de la page maître asp.net.)

Les méthodes statiques ne sont pas insortingnsèquement sûres. Ils ne sont pas traités différemment par le CLR que par les méthodes d’instance. La différence est que l’on devrait généralement essayer de les rendre sécuritaires pour les threads. (Je ne peux pas penser à des méthodes statiques .NET BCL qui ne sont pas sûres pour les threads.) Les méthodes d’instance ne sont souvent pas sûres pour les threads car le modèle typique est de créer un object et de l’utiliser à plusieurs resockets. doit être utilisé à partir de plusieurs threads, la coordination impliquée implique de s’assurer que l’object est utilisé en toute sécurité. Dans de nombreux cas, il est plus approprié de faire dans le code de coordination que dans l’object lui-même. (Habituellement, vous voulez que des séquences complètes d’opérations soient atomiques, ce qui ne peut pas être fait dans l’object.)

Votre classe Timer n’est certainement pas sûre pour les threads: deux threads peuvent piétiner les données les uns des autres facilement, et rien ne peut empêcher un thread d’utiliser des données “obsolètes” lors du calcul de la durée.

Utilisez plutôt la classe Stopwatch – c’est ce qui est là pour ça. Certes, si vous voulez utiliser une instance de plusieurs threads, vous devrez prendre les mesures habituelles pour assurer la sécurité, mais vous serez dans une bien meilleure position en général. Certes, Stopwatch est loin d’être parfait – voyez cette question et le commentaire ci-dessous pour plus de détails – mais c’est au moins pour quoi le type est conçu. (Qui sait, ça peut être fixé un peu de temps …)

Il y a une bonne discussion ici qui se concentre davantage sur les mécanismes et les raisons pour lesquelles votre exemple n’est pas sûr pour les threads.

Pour résumer, premièrement, vos variables statiques seront partagées. Si vous pouviez en faire des variables locales, même si elles sont locales à une méthode statique, elles obtiendraient quand même leur propre frame de stack, et par conséquent, elles seraient sûres. De plus, si vous protégez par ailleurs vos variables statiques (c.-à-d., Les verrous et / ou les autres techniques de programmation multithread mentionnées par d’autres dans ce thread), vous pouvez également rendre votre exemple de classe statique thread-safe.

Deuxièmement, comme votre exemple ne prend pas en compte les instances de variables externes que vous modifiez ou dont un autre thread peut modifier l’état, votre exemple est également thread-safe à cet égard.

Votre classe de timer n’est certainement pas compatible avec les threads. Vous devez créer une classe normale et l’instancier chaque fois que vous devez mesurer le temps:

 Timer timer = new Timer(); timer.Start(); //... timer.Stop(); decimal duration = timer.Duration(); 

Mieux encore, il existe une classe .NET intégrée qui fait exactement cela:

 Stopwatch sw = Stopwatch.StartNew(); sw.Stop(); TimeSpan duration = sw.Elapsed; 

Oui, vous avez raison, les membres / accesseurs statiques de cette classe vont les écraser par différents utilisateurs.

C’est pourquoi vous avez des instances et des membres non statiques.