Esperar algunos segundos sin el bloqueo de la interfaz de usuario de ejecución de

Me gustaría esperar algunos segundos entre dos instrucción, pero SIN bloquear la ejecución.

Por ejemplo, Thread.Sleep(2000) no es bueno, debido a que bloquea la ejecución.

La idea es que puedo llamar a un método y, a continuación, puedo esperar X segundos (20 por ejemplo) detección de un evento que viene. Al final de los 20 segundos que debo hacer alguna operación dependiendo de lo que pasó en los 20 segundos.

  • Podemos ver un ejemplo de lo que quieres decir? Esto es muy amplia.
  • Además, hay un tipo de aplicación que estás construyendo? Una Consola, WPF, Winforms, ASP.NET app o algo más?
  • ¿Siempre quiere esperar X segundos para que el evento o se puede hacer alguna operación tan pronto como el hecho de que si viene y hacer alguna otra operación si el evento no viene dentro de X segundos, es decir, como un tiempo de espera?
InformationsquelleAutor user3376691 | 2014-03-03

7 Kommentare

  1. 84

    Creo que lo que está después es Tarea.El retraso. Esto no bloquear el hilo de Dormir y esto significa que usted puede hacer esto utilizando un solo hilo usando el modelo de programación asíncrona.

    async Task PutTaskDelay()
    {
        await Task.Delay(5000);
    } 
    
    private async void btnTaskDelay_Click(object sender, EventArgs e)
    {
        await PutTaskDelay();
        MessageBox.Show("I am back");
    }
    • Gracias, parece interesante. Sólo tengo un proble, El async y await no son reconocidos desde C#. ¿Sabes por qué?
    • Son bastante nuevas incorporaciones a la .Net Framework y se añadieron con la versión 4.5 en Visual Studio 2012 y 2013. Hay un paquete de nuget en nuget.org/packages/Microsoft.Bcl.Async si esto le ayuda.
    • Gracias. He instalado Visual Studio Express 2013 y se ha async y await ahora. Pero cuando se desea utilizar el método de Retraso de la Tarea, no existe. Los únicos métodos permitidos son Iguales, RefernceEquals, WaitAll y WaitAny… ¿sabes por qué?
    • Tarea.Delay(10).Wait() funciona, pero va a bloquear la ejecución de la rosca, es decir, la interfaz de usuario no responde. A menos que ese es el comportamiento que usted quiere que me gustaría utilizar el async patrón.
    • Es necesario para btnTaskDelay_Click a ser async y uso await para PutTaskDelay()? No es suficiente que sólo esperan la Task.Delay() dentro de PutTaskDelay()?
    • Usted incluso no necesita PutTaskDelay() acaba de llamar await Task.Delay(5000); directamente
    • No es apropiado para hacer estos cambios a otros las respuestas de las personas. Comentar que está muy bien, pero si alguien prefiere extraer el código en un método, esa es su decisión.
    • Yo no era la eliminación de cualquier cosa, que me acaba de añadir algo útil.
    • Y eso no es apropiado en una edición. Si usted tiene su propia solución para agregar, puede publicar su propia respuesta, pero la adición de su propia solución en otra persona de la respuesta no es adecuada.
    • que no era mi propia solución. Que era solo una mejora de su solución.
    • Era de su versión mejorada. El punto de stands. Si usted viene para arriba con una manera para que una solución sea mejorado, publicar un comentario para el autor decide hacer el cambio, o después de su alternativa como su propia respuesta (citando una obra derivada según corresponda). La edición de su nueva versión a otra respuesta no es adecuada.
    • ok yo te tengo

  2. 25

    Yo uso:

    private void WaitNSeconds(int segundos)
    {
        if (segundos < 1) return;
        DateTime _desired = DateTime.Now.AddSeconds(segundos);
        while (DateTime.Now < _desired) {
             System.Windows.Forms.Application.DoEvents();
        }
    }
    • Tengo una aplicación que se queda en .NET 3.5 (No async/await). Este era perfecto.
    • Esta solución es efectiva si no se puede actualizar .NET 4.5, pero va a consumir excesivos recursos de la CPU sin un pequeño ajuste. Ver mi respuesta para una explicación detallada.
    • Cuidado de la maldad oculta dentro de DoEvents. consulte blog.codinghorror.com/is-doevents-evil o blog.codinghorror.com/is-doevents-evil-revisited
    • Watch out! Si utiliza esta espera en el controlador de evento load del formulario, a continuación, su forma sólo se mostrará después de la espera el paso del tiempo.
    • has salvado mi vida gracias
    • Este va a chupar la CPU.

  3. 12

    Este es un buen caso para el uso de otro hilo:

    //Call some method
    this.Method();
    
    Task.Factory.StartNew(() =>
    {
        Thread.Sleep(20000);
    
        //Do things here.
        //NOTE: You may need to invoke this to your main thread depending on what you're doing
    });

    El código de arriba espera .NET 4.0 o superior, de lo contrario, pruebe con:

    ThreadPool.QueueUserWorkItem(new WaitCallback(delegate
    {
        Thread.Sleep(20000);
    
        //Do things here
    }));
    • Sólo voy a añadir un comentario a mi propia edad responder aquí a decir que prefiero el asíncrono de los métodos mencionados en las otras respuestas son tanto más limpio y mejor práctica. Si no lo has leído ya en asincrónica, yo recomiendo hacerlo.
  4. 11

    Omar solución es decente* si no puede actualizar su entorno .NET 4.5 con el fin de obtener acceso a la async y await Api. Dicho esto, hay aquí es un cambio importante que debe ser hecho con el fin de evitar un mal rendimiento. Un ligero retraso debe agregarse entre las llamadas a la Aplicación.DoEvents() con el fin de evitar el uso excesivo de CPU. Mediante la adición de

    Thread.Sleep(1);

    antes de la llamada a la Aplicación.DoEvents(), puede agregar un delay (1 milisegundo) y evitar la aplicación del uso de todos los ciclos de cpu disponibles.

    private void WaitNSeconds(int seconds)
    {
        if (seconds < 1) return;
        DateTime _desired = DateTime.Now.AddSeconds(seconds);
        while (DateTime.Now < _desired) {
             Thread.Sleep(1);
             System.Windows.Forms.Application.DoEvents();
        }
    }

    *Ver https://blog.codinghorror.com/is-doevents-evil/ para una discusión más detallada sobre los peligros potenciales de la utilización de la Aplicación.DoEvents().

    • En el momento en el que he publicado esta solución, yo no cumplir con el mínimo de reputación necesaria para añadir un comentario a Omar de la solución. Por ahora estoy guardando esta respuesta abierta, ya que implica el formato de código.
    • Yo lo uso para programar las aplicaciones MVVM desde Fw 3.5 4.5.1 e incluso con todos los nuevos recursos, a veces simples soluciones a un problema son los mejores
  5. 4

    Si usted no desea bloquear cosas y también no desea utilizar multi threading, aquí está la solución para usted:
    https://msdn.microsoft.com/en-us/library/system.timers.timer(v=vs 110).aspx

    El Subproceso de interfaz de usuario no está bloqueado y el temporizador de espera 2 segundos antes de hacer algo.

    Aquí está el código que viene desde el enlace de arriba:

            //Create a timer with a two second interval.
        aTimer = new System.Timers.Timer(2000);
        //Hook up the Elapsed event for the timer. 
        aTimer.Elapsed += OnTimedEvent;
        aTimer.Enabled = true;
    
        Console.WriteLine("Press the Enter key to exit the program... ");
        Console.ReadLine();
        Console.WriteLine("Terminating the application...");
    • Hace mucho tiempo, PERO tengo una asp.net la página que se encargan de Puestos principalmente backend cosas que necesitaba un temporizador y esto hizo que el trabajo no se bloquea.
  6. 2

    realmente me disadvise contra el uso de Thread.Sleep(2000), debido a varios motivos (algunos se describe aquí), pero sobre todo porque no es útil cuando se trata de la depuración y pruebas.

    Recomiendo el uso de un C# Temporizador en lugar de Thread.Sleep(). Temporizadores permiten realizar métodos con frecuencia (si es necesario) Y son mucho easiert para su uso en las pruebas! Hay un muy buen ejemplo de cómo utilizar un temporizador a la derecha detrás de la hipervínculo – acaba de poner su lógica de «lo que sucede después de 2 segundos» a la derecha en la Timer.Elapsed += new ElapsedEventHandler(OnTimedEvent); método.

  7. 0

    Mirar en System.Threading.Timer clase. Yo creo que esto es lo que estás buscando.

    La ejemplo de código de MSDN parece mostrar esta clase haciendo muy similar a lo que estamos tratando de hacer (verificación de estado después de cierto tiempo).

    • Se puede proporcionar una pequeña muestra?
    • Hay un ejemplo en el enlace en mi post. ¿Qué hace falta para que me agregue a?
    • Se debe añadir un ejemplo para su respuesta todavía proporciona un valor, incluso cuando la relación se convierte en inválida. También, «mira en foobar», dispone de poco valor por sí mismo.
    • Yo no la bandera de esta respuesta como «no respuesta», pero algunos usuarios ya lo hice.

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein