none
¿Cómo puedo mandar notificaciones con la aplicación cerrada en Windows Forms C#? RRS feed

  • Pregunta

  • Tengo una aplicación de Windows Forms para Windows. Es una aplicación de alarma. 

    En el formulario 1 (formulario principal) hay 2 datetimepicker y 2 botones. El datetimepicker 1 está vinculado con el botón 1. Cuando presiona el botón 1 debe enviarle una notificación (con el control de notificación: NotifyIcon) y el otro datetimepicker y el botón 2 son para el mismo, sólo una segunda alarma.

    Eso es todo lo que he intentado y todo lo que sé. El problema ahora es que no puedo enviar las notificaciones con la aplicación cerrada, que básicamente es el propósito de la aplicación. Lo único que supongo que podría hacer es crear otro hilo o algo similar, pero que funcione como una tarea normal, en segundo plano, como las que podrías cancelar en el administrador de tareas.

    lunes, 2 de julio de 2018 6:21

Todas las respuestas

  • ¿Qué entiendes por "cerrada"? Si te refieres a que se ha salido del programa y se ha descargado de memoria, entonces no puede enviar ninguna notificación. Pero, en cambio, si al cerrarlo haces simplemente un .Hide() del form, no se verá nada en pantalla pero seguirá siendo capaz de presentar las alertas. Puedes interceptar el evento Closing y hacer un e.Cancel para cancelar el cierre y en su lugar llamar a Hide. El efecto visual será que se ha cerrado, pero la aplicación seguirá cargada en memoria.

    Lo de lanzar un hilo también funciona, en el sentido de que el hilo continuará ejecutándose aunque se cierre la interfaz de la aplicación. Pero ojo, desde el otro hilo no podrás acceder al NotifyIcon (dará un "illegal cross-thread call") a no ser que antes uses el .Invoke para trasladar la ejecución al hilo principal.

    lunes, 2 de julio de 2018 6:46
  • Gracias, pero alguna idea sobre cómo hacer el hilo con código?
    • Editado SebGM2018 lunes, 2 de julio de 2018 17:09
    lunes, 2 de julio de 2018 17:09
  • Para hacer el hilo puedes hacerlo así:

    using System.Threading;
    // ...
    
    Thread t = new Thread(new ThreadStart(MiSubrutina));
    t.IsBackground = false;
    t.Start();
    
    // ...
    
    private void MiSubrutina()
    {
        // Esto se ejecuta dentro del hilo
    }
    

    Observa que te he puesto "t.IsBackground = false;". Esto en realidad es superfluo, ya que false es el valor predeterminado. Pero lo he puesto expresamente para dejar claro que esto es lo que hace que el hilo se siga ejecutando aunque cierres la interfaz de la aplicación. Si le pones true en lugar de false, el hilo termina automáticamente cuando se cierra la interfaz.

    lunes, 2 de julio de 2018 19:26
  • Muchas gracias, pero tengo una duda: Entonces el t.IsBackGround lo dejo en = false? O en algún momento lo tengo que cambiar a true? Y aparte lo que me decía del método Invoke(); se debería usar en el momento de interactuar con la interfaz? Es decir, al mandar la notificación y ya?
    martes, 3 de julio de 2018 4:19
  • Sí, el IsBackground déjalo en false. Lo de ponerlo a true en tu caso no tienes que hacerlo; solo lo mencionaba por si acaso en alguna otra ocasión tú o algún otro visitante del foro tiene necesidad de trabajar en multihilo pero no quiere que el hilo quede rodando en memoria después de cerrar la ventana (que no es tu caso).

    Lo del Invoke solo se usa en el momento de llamar a la notificación. Suponiendo que instanciaste ya un NotifyIcon llamado notiFyIcon1 antes de lanzar el hilo, cuando desde el hilo quieras activarlo harías algo parecido a esto:

    notiFyIcon1.Invoke(new MethodInvoker(()=>{notiFyIcon1.Text="lo que sea"; notiFyIcon1.Visible=true;}));

    En este ejemplo te he construido el parámetro del Invoke usando una expresión lambda, pero puedes hacerlo de otras maneras, solo se trata de pasar un delegado que apunte a la función que quieras ejecutar.

    martes, 3 de julio de 2018 5:17