visual tipos modal mensaje mandar formulario elementos ejemplos ejemplo dialogo cuadros cuadro c# winforms messagebox

c# - tipos - Cuadro de diálogo de diálogo a veces oculto detrás del formulario principal



showdialog c# ejemplo (5)

Algunos de nuestros usuarios no técnicos tienen problemas en los que a veces se puede mostrar un cuadro de diálogo MessageBox en nuestra aplicación detrás del formulario principal y la aplicación no acepta ninguna entrada hasta que se descarta el cuadro de mensaje (que no pueden ver).

La aplicación está escrita en C # y los cuadros de mensajes son estándar, por ejemplo, el código puede ser tan simple como MessageBox.Show (mensaje, título) y los cuadros de mensajes pueden ser creados por el hilo principal de la interfaz de usuario (es decir, no un hilo de fondo). La aplicación no tiene que ejecutarse a pantalla completa, pero el 90% de nuestros usuarios la ejecutan a pantalla completa.

La mayoría de las veces ((tal vez> 99%) los cuadros de mensajes se muestran correctamente y nunca he podido ver cómo va mal, pero he visto una máquina cuando ha fallado.

Una cosa que noté es que si tiene una aplicación que muestra un cuadro de diálogo, entonces cuando mira su administrador de tareas, normalmente solo verá una entrada en la lista de aplicaciones. Cuando el cuadro de mensaje esté oculto, verá dos entradas, una para la aplicación principal y otra para este cuadro de mensaje.

Es bastante fácil solucionar el problema una vez que sabes lo que ha sucedido, pero algunos de nuestros usuarios no técnicos se confunden y terminan apagando sus computadoras. (Y los que usan Remote Desktop están aún más confundidos cuando eso no resuelve el problema).

No creo que esté relacionado con el sistema operativo, ya que lo he visto en Vista y se me ha dicho que también ocurre en una sesión de terminal en un servidor Windows 2003.

¿Alguien sabe por qué sucede esto y, lo que es más importante, si se puede hacer algo para evitarlo?


¿Es siempre el mismo cuadro de mensaje (para el mismo mensaje?) Que viene de la misma forma?

Idealmente, deberías intentar encontrar alguna forma de reproducir el problema a voluntad, o al menos automáticamente. Esto hará que su depuración sea más fácil y luego puede estar seguro de que su cambio futuro habrá corregido el error, en lugar de tener que esperar unas semanas para recibir los comentarios de sus usuarios.

Si siempre es el mismo mensaje y en la misma ventana, como resultado de la misma acción, y si la llamada MessageBox es razonablemente fácil de activar desde un punto de vista del usuario y si su UI es relativamente estándar, puede automatizar la UI. con una AutoIT comandos AutoIT y haga que se ejecute en un bucle hasta que se AutoIT el problema.

Y / o, podría crear un "debug" -build de sus aplicaciones que podría darle a algunos usuarios (preferiblemente los que parecen encontrarse con el problema más a menudo) que escribirían el contenido de un objeto StackFrame en un archivo de registro o algo similar cada vez antes de llamar a un MessageBox (puede crear una envoltura alrededor del MessageBox para que esto sea más fácil).

Luego, cuando uno de sus usuarios tiene el problema, puede mirar el archivo de registro y ver de dónde proviene (archivo de código fuente, línea, pila de llamadas, etc.). También puede comparar esto con los registros de otros usuarios y ver si, cada vez, el MessageBox proviene de la misma ubicación o si varía. Esto le mostraría desde dónde se llama el MessageBox problemático y desde dónde.

Puede haber soluciones más sencillas (especialmente si su aplicación tiene muchos ensamblajes) que involucran algún depurador .Net que adjuntaría a su aplicación cuando ocurra el problema para ver la pila de llamadas, etc., pero solo lo hice con aplicaciones nativas (usando OllyDbg) hasta ahora y no .Net. Otros pueden ser capaces de ampliar más en esta idea ...


Confirma el problema. Lo que hacemos para solucionarlo es lo siguiente: 1. Ejecutar nueva tarea y mostrar el cuadro de mensaje 2. En el subproceso de la interfaz de usuario principal mientras la tarea aún se está ejecutando, espere en el bucle que hace DoEvents. Algo como esto

ACTUALIZADO 2015-12-17. Problema reproducido ayer. Para volver a publicar en mi caso: minimice la aplicación, aparece una ventana emergente de "espera" (en nuestro caso, después de un tiempo de inactividad), luego en la barra de tareas, haga clic en el icono principal de la aplicación. Esto "oculta" la ventana emergente, por lo que no es posible mostrarlo en la pantalla. El siguiente código fue probado y resuelve el problema. Pero todavía no entiendo qué / por qué sucede.

private static DialogResult ShowMessageBox( string message, string caption, MessageBoxButtons buttons, MessageBoxIcon icon) { var showMessageBoxTask = new Task<DialogResult>(() => { var form = new Form() {TopMost = true}; var result = MessageBox.Show( form, PrepareMessage(message), caption, buttons, icon); form.Dispose(); return result; }); showMessageBoxTask.Start(); while (!showMessageBoxTask.IsCompleted && !showMessageBoxTask.IsFaulted) { Application.DoEvents(); } return showMessageBoxTask.Result; }


Dice "los cuadros de mensajes pueden crearse mediante el subproceso de la interfaz de usuario principal", lo que supongo significa que no siempre los crea el subproceso de la interfaz de usuario principal. Su problema suena como MessageBox.Show es llamado ocasionalmente desde otro hilo.


En el formulario principal, agregue esto antes de MessageBox.Show ():

this.TopMost = falso;


Algunas sobrecargas del método MessageBox.Show() toman un parámetro IWin32Window como primer argumento. Si pasa su Formulario como primer argumento, debería evitar que esto suceda.