2010-05-21 15 views
6

que necesitan de alguna manera para hacer lo siguiente eficiente en C#:C# parada y continuar

Hacer una parada de la ejecución del programa hasta que se cambie cierto valor.

Nota: no quiero hacerlo con un bucle while para evitar el desperdicio de energía de la CPU ..

Editar: Y quiero que responda tan pronto como sea posible después de valor ha cambiado ..

Editar: Esto estará dentro de mi método de clase que se llama por otro código, sin embargo, el valor que se comprobará está dentro de mi clase ... Se espera que el método espere hasta que otros c oda a evaluar y cambiar el valor de mi .. entonces debe seguir para hacer su trabajo .. lamentablemente esto se hace muchas veces (por lo que necesitan para cuidar de rendimiento)

+0

¿Es esta solicitud un servicio de Windows? No especifica, y realmente no tiene sentido detener la ejecución literalmente en una aplicación interactiva (impulsada por eventos). – Aaronaught

+5

Sus requisitos son contradictorios.Rechaza la espera de ocupado debido a su consumo de energía, y requiere que ** sea lo más receptivo posible **, pero la espera ocupada es lo ** más receptivo posible **. Lo que sería mejor es que nos haya informado sobre su * presupuesto *. "Lo más rápido posible" no nos dice nada; "dentro de un milisegundo" nos dice bastante. Una solución que responde dentro de un milisegundo podría ser bastante diferente de una solución que responda a un microsegundo o a un segundo. –

+1

¿a qué se refiere exactamente al hacer detener la ejecución? ¿Es un hilo que se ejecuta constantemente que tienes que interrumpir en un cierto punto? ¿Cómo piensas hacer que se detenga? ¿o es más como un evento breve que te gustaría que ocurra en un cambio de valor? –

Respuesta

15
+0

No hay 'Monitor.Set'. ¿Quisiste decir 'Monitor.Pulse' o' Monitor.PulseAll'? – Aaronaught

+0

@ Aaronaught- sí, sí –

+0

Si quieres dormir completamente sin ningún tipo de vueltas, este es el camino a seguir. Sin embargo, esto requiere que el código que establece el valor sepa cómo pulsar en el objeto correcto o su código nunca se activará. – Stephan

6
while(some-condition-here) 
{ 
    Thread.CurrentThread.Sleep(100); // Release CPU for 100ms 
} 

Se llama spin-dormir pienso. Por supuesto, puedes ajustar el 100 a lo que sientas que esté en forma. Básicamente es el tiempo de espera para cada control.

Hay otras maneras de hacerlo, pero esta es la más fácil y es bastante eficiente.

De hecho, es referencia en este libro electrónico:

Threading in C# by Joseph Albahari: Part 2: Basic Synchronization

+0

Lo he usado antes, pero no soy fanático de él. (Así que no modificaré tu respuesta hacia arriba o hacia abajo.) Siempre me "olió" mal. – Pretzel

+0

@Pretzel Me he referido a un libro (e-book) que habla de ello. – Aren

+0

El hecho de que esté en un libro no lo hace correcto. Además, para citar al autor, "¡Tal vez su mayor uso es cuando un programador se da por vencido para lograr que una construcción de señalización más compleja funcione!" –

7

Si el valor que está a la espera de que se establezca en otro lugar en la misma aplicación se puede utilizar un mango de espera:

AutoResetEvent waitHandle = new AutoResetEvent(); 
... 
//thread will sleep here until waitHandle.Set is called 
waitHandle.WaitOne(); 
... 
//this is where the value is set 
someVar = someValue; 
waitHandle.Set(); 

(tenga en cuenta que el WaitOne y Set tienen que ocurrir en hilos separados como se WaitOne bloquear el hilo al que se llama)

Si no tiene acceso al código que cambia el valor, la mejor manera de hacerlo es, como han dicho otros, utilizar un ciclo para verificar si el valor ha cambiado y use Thread.Sleep() para no utilizar tanto tiempo de procesador:

while(!valueIsSet) 
{ 
    Thread.Sleep(100); 
} 
+0

/de acuerdo ... esta es la mejor manera posible – csauve

+0

Si el objetivo es BLOQUEAR un hilo, esta es la mejor manera. Para bloquear el hilo principal y evitar nuevas entradas hasta que ocurra el evento, coloque el .WaitOne() en el hilo principal. En otro hilo, donde el valor que desencadena la activación, coloque el .Set(); – Roast

3

Puede usar el patrón de diseño Observer. Está diseñado para resolver problemas como el tuyo.

Este patrón contiene principalmente un sujeto y un observador. Puede tenerlo para responder a cualquier cambio y muy rápidamente.

Puede encontrar más información y código de ejemplo here

+0

Si la arquitectura lo permite (es decir, usted tiene el control sobre lo que está monitoreando), esta puede ser una buena solución. Obtienes una respuesta muy rápida porque recibes el evento inmediatamente después de que haya ocurrido el cambio. La advertencia principal es que se está ejecutando en el contexto del hilo que realizó el cambio, que a veces puede ser problemático. –