¿Los métodos estáticos son seguros?

Tengo una clase de temporizador estático que CUALQUIER página web llamará para calcular cuánto tiempo ha tardado en construirse cada página.

Mi pregunta es si las clases de Static son seguras? En mi ejemplo, ¿los usuarios simultáneos causarán un problema con mis horas de inicio y finalización? por ejemplo, un subproceso diferente sobreescribiendo mis valores de inicio y fin.

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; } } 

¿Debería esta clase ser una clase no estática?

(Esta clase se llamará desde la página maestra asp.net).

Los métodos estáticos no son inherentemente seguros para subprocesos. El CLR no los trata de manera diferente a los métodos de instancia. La diferencia es que, por lo general, uno debe tratar de hacerlos seguros para subprocesos. (No puedo pensar en ningún método .NET BCL estático que no sea seguro para subprocesos.) Los métodos de instancias a menudo no son seguros para subprocesos porque el patrón típico es crear un objeto y usarlo repetidamente desde un subproceso, y si tiene que ser utilizado desde múltiples hilos, la coordinación involucrada incluye asegurarse de que el objeto se use de manera segura. En muchos casos, es más apropiado hacerlo en el código de coordinación que en el objeto mismo. (Por lo general, desea hacer secuencias completas de operaciones atómicas de manera efectiva, algo que no se puede hacer dentro del objeto).

La clase del Timer definitivamente no es segura para subprocesos: dos subprocesos pueden pisar fuerte los datos de los demás con facilidad, y no hay nada que impida que un subproceso use datos “obsoletos” al calcular la duración.

Use la clase Stopwatch lugar – para eso está ahí. Es cierto que si desea utilizar una instancia de múltiples hilos, deberá seguir los pasos normales para garantizar la seguridad, pero en general se encontrará en una posición mucho mejor. Es cierto que Stopwatch está lejos de ser perfecto también – vea esta pregunta y el comentario a continuación para obtener más detalles – pero al menos es para lo que está diseñado el tipo. (Quién sabe, se puede arreglar algún tiempo …)

Aquí hay una buena discusión que se centra más en los mecanismos y las razones de por qué su ejemplo no es seguro para subprocesos.

Para resumir, primero, sus variables estáticas serán compartidas. Si pudieras convertirlas en variables locales, aunque sean locales para un método estático, seguirían teniendo su propio marco de stack y, por lo tanto, serían seguros para la ejecución de subprocesos. Además, si protege sus variables estáticas (es decir, lockings y / u otras técnicas de progtwigción de subprocesos múltiples mencionadas por otros en este hilo) también puede hacer que su muestra estética sea segura para subprocesos.

En segundo lugar, como su ejemplo no toma instancias de variables externas que modifique o cuyo estado pueda ser afectado por otro subproceso, su ejemplo también es seguro para subprocesos.

Tu clase de temporizador definitivamente no es segura para subprocesos. Debe crear una clase normal y crear una instancia cada vez que necesite medir la hora:

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

Mejor aún, hay una clase .NET incorporada que hace exactamente eso:

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

Sí, tiene razón, los miembros / accesadores estáticos de esta clase provocarán que otros usuarios los sobrescriban.

Es por eso que tienes instancias y miembros no estáticos.