Tengo un sistema que toma muestras. Tengo varios hilos de clientes en la aplicación que están interesados en estos ejemplos, pero el proceso real de tomar una muestra solo puede ocurrir en un contexto. Es lo suficientemente rápido como para bloquear el proceso de llamada hasta que se realiza el muestreo, pero lo suficientemente lento como para no querer que varios hilos acumulen solicitudes. Se me ocurrió con este diseño (pelado abajo a los detalles mínimos):¿Es este un diseño de sincronización entrelazado correcto?
public class Sample
{
private static Sample _lastSample;
private static int _isSampling;
public static Sample TakeSample(AutomationManager automation)
{
//Only start sampling if not already sampling in some other context
if (Interlocked.CompareExchange(ref _isSampling, 0, 1) == 0)
{
try
{
Sample sample = new Sample();
sample.PerformSampling(automation);
_lastSample = sample;
}
finally
{
//We're done sampling
_isSampling = 0;
}
}
return _lastSample;
}
private void PerformSampling(AutomationManager automation)
{
//Lots of stuff going on that shouldn't be run in more than one context at the same time
}
}
Es esto seguro para su uso en el escenario que he descrito?
+ 1 para la solución más simple. –
El TryEnter probablemente sea mejor desde la perspectiva del mantenimiento, ya que es probable que más personas estén familiarizadas con Monitor.TryEnter que con Interlocked.CompareExchange. No estoy demasiado preocupado por los gastos generales en este caso, ya que solo estoy tomando muestras unas pocas veces por segundo. Cuando realmente realiza el muestreo, la sobrecarga del proceso de muestreo en sí será bastante más que la primitiva de bloqueo, estoy seguro. –
Me gusta el Monitor.TryEnter, pero ¿no deberíamos usar el ReaderWriterLockSlim en estos días? http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim_members.aspx –