2009-08-24 76 views
6

Quiero esperar 15 segundos, luego el control debería reanudarse desde la siguiente declaración.¿Cuál es la mejor manera de esperar cierto tiempo (digamos 10 segundos) en C#?

No tengo nada más que hacer mientras espero (Solo estoy esperando).

Sé que hay Thread.Sleep(15000). Lo que no sé es el mejor método para esperar? ¿Cuáles son las limitaciones de esto?

El código sería así:

Method() 
{ 
    statement 1; 
    statement 2; 
    //WaitFor 15 secs here; 
    statement 3; 
} 
+0

Thread.Sleep (15000) está muy bien para C#. Para WinForms, WPF o ASP.NET es un desastre. –

+0

Cerca de duplicados: http://stackoverflow.com/questions/1091710, http://stackoverflow.com/questions/407130, http://stackoverflow.com/questions/1208103 y http://stackoverflow.com/questions/903688. –

Respuesta

2

intentar algo así como lo siguiente:

void Method() 
{ 
    console.log('statement 1'); 
    console.log('statement 2'); 

    var timer = new System.Threading.Timer(
     o => // timer callback 
     { 
      console.log('statement 2'); 
     }, 
     15000, // Delay 
     0  // Repeat-interval; 0 for no repeat 
    ); 
} 

Sintaxis es C# 3.0, utiliza una expresión lambda para crear efectivamente un cierre alrededor de declaración # 3. Con esto, puedes usar cualquier variable local de Método. Una cosa a tener en cuenta, sin embargo, es que con este método, o cualquier otro método basado en el temporizador ... la función volverá inmediatamente después de crear el temporizador. La función no se bloqueará hasta que se ejecute el temporizador.Para lograr eso, lo único que se me ocurre es usar hilos y hacer que el método bloquee una señal (es decir, WaitHandle, ResetEvent, etc.) hasta que finalice la llamada programada en el otro hilo.

+4

Hay un problema con este ejemplo. No funcionará de manera confiable, ya que no se guarda ninguna referencia al objeto 'Timer' en ninguna parte. Por lo tanto, está sujeto a la recolección de basura. Cuanto más larga sea su demora, mayor será la probabilidad de que esto sea un problema. Desde MSDN: * Siempre que use un temporizador, debe mantener una referencia al mismo. Al igual que con cualquier objeto administrado, un temporizador está sujeto a la recolección de basura cuando no hay referencias a él. El hecho de que un temporizador todavía esté activo no impide que se recopile. * – Thorarin

+0

@Thorarin: Ah, buen punto. Me olvidé por completo de ese pequeño hecho. Veré si puedo corregir el ejemplo. – jrista

+0

Si desea enviar la devolución de llamada en la secuencia de la interfaz de usuario, debe usar 'System.Windows.Forms.Timer' en su lugar. –

1

Siempre se puede utilizar un temporizador y luego ejecutar código después de que el período de tiempo establecido. Sin embargo, si no tienes que hacer nada y solo quieres esperar en un punto particular del código, entonces creo que Thread.Sleep (150000); es suficiente. [Editar: ortografía]

2

Thread.sleep parece una cosa sensata si no hay nada más que hacer mientras espera. Pone el hilo a dormir durante ese tiempo para que no utilice ningún recurso de CPU.

+0

Sí, cualquier otro método usaría CPU, y no lo desea si todo lo que necesita hacer es esperar ... – awe

+0

Es particularmente útil en pruebas unitarias donde necesita simular delta de tiempo. El método no puede salir, por lo que Thread.Sleep() es menos malo en esta situación particular. Durante largos intervalos de tiempo he falsificado esto al modificar la hora del sistema. Algo así como poner la computadora en una máquina del tiempo. Cuando se realiza la prueba, el tiempo del sistema vuelve a la normalidad. –

11

La desventaja de Thread.Sleep es si esto se llama en su subproceso GUI (el subproceso que procesa eventos GUI, por ejemplo, un método de controlador de clic de botón, o un método llamado desde un controlador de clic de botón, etc.) su aplicación parecerá congelarse y no responder durante esos 15 segundos.

Sería perfectamente correcto si hubiera creado explícitamente un hilo separado y lo hubiera llamado Thread.Sleep, asumiendo que no le importa que el hilo no haga nada durante 15 segundos.

La alternativa sería crear un temporizador e iniciarlo después de stmt 2, y colocar stmt 3 en el controlador de eventos Tick para el temporizador, y también detener el temporizador en ese controlador.

6

Puede que esta no sea una respuesta directa a su pregunta. Yo diría que verifique si el flujo de su proceso es mejor que comprobar si el código es mejor ;-)

¿Está esperando 15 segundos para asegurarse de que stmt2; ¿Esta completo? Si es así, agregar un controlador, tan pronto como se ejecute stmnt 2, sería una mejor solución (?)

También puede usar un temporizador para esperar. Thread.sleep es un mal diseño. Tenemos una pregunta similar que habla del comparison using Thread.sleep and Timer.

0

Si siempre quiere esperar un tiempo determinado, entonces Sleep es útil. Obviamente, no debe hacer esto en un hilo donde se esperan respuestas oportunas.

Tenga en cuenta que su hilo dormirá durante todo el tiempo. Si por alguna razón quieres que el hilo se reanude más rápido, es mejor que utilices la señalización o las devoluciones de llamada. Al usar cualquiera de estos en lugar de Sleep, minimizará el innecesario tiempo de espera.

-1

que no lo hacen seguro 100%, pero si realmente necesita su método para devolver después de esperar 15 segundos, seguir los siguientes pasos:

 

Method() 
{ 
    stmt1(); 
    stmt2(); 

    int time = DateTime.Now.Millisecond; 
    while (15*1000 > DateTime.Now.Millisecond - time) 
    { 
     Thread.Sleep(10) 
     Application.DoEvents(); 
    } 
    stmt3(); 
} 
 
0
void Method() 
{ 
    Statement1(); 
    Statement2(); 

    // Start the timer for a single 15 second shot. 
    // Keep a reference to it (Mytimer) so that the timer doesn't get collected as garbage 
    Mytimer = new System.Threading.Timer((a) => 
     { 
      // Invoke the 3rd statement on the GUI thread 
      BeginInvoke(new Action(()=>{ Statement3(); })); 
     }, 
    null, 
    15000, // 15 seconds 
    System.Threading.Timeout.Infinite); // No repeat 
} 
Cuestiones relacionadas