.net - icon - ¿Existe una versión no bloqueante de MessageBox.Show(o algo así)?
messagebox.show c# ejemplos (4)
¿Qué hay de agregar un NotifyIcon a su aplicación y mostrar una punta de globo ? El inconveniente es que la notificación desaparecerá en poco tiempo, pero tal vez sea mejor para sus usuarios si no es necesario que actúen.
Hay más sugerencias sobre esta pregunta .
Actualización retrasada
Estoy aceptando la respuesta de MUG4N a esta pregunta, y también quiero responder a algunas de las críticas que se hicieron contra ella.
ChrisF dijo:
... no puedes hacer llamadas de UI directamente desde hilos de fondo.
Esta es una afirmación general, y no es 100% cierta. Permítanme señalar algunos hechos:
En realidad, puede hacer todas las llamadas de UI que desee si configura
Control.CheckForIllegalCrossThreadCalls = false
. "Ack!" Te oigo decir " Nunca hagas eso!" Sí, sí, pero ¿por qué ? La respuesta: porque a veces esto corromperá la memoria.Las clases de control en
System.Windows.Forms
no están escritas para ser seguras para subprocesos, por lo que a veces actualizarlas desde subprocesos en segundo plano puede dañar la memoria. Pero si esto solo sucede a veces y no siempre , lo que me dice es que no es la llamada del código UI en sí , sino la colisión potencialmente insegura del código UI que puede causar excepciones .Para reforzar el punto 1, considere esto: la forma "segura" de invocar el código de UI desde un hilo en segundo plano es hacerlo mediante
Control.Invoke
oControl.BeginInvoke
, ¿verdad? Pero esta es una llamada UI ; es solo la llamada de la interfaz de usuario que debemos hacer si estamos actualizando la GUI desde un subproceso que no es GUI. Lo que quiero decir es que, claramente, no es simplemente invocar el método "cualquiera" en un objeto deControl
desde un hilo externo que va a causar el caos (si ese fuera el caso, entonces ni siquiera podríamos llamar aInvoke
y estaríamos atascados). completamente). Una vez más, es la colisión potencial de llamadas de UI separadas que no pueden ocurrir de manera segura y simultánea lo que resultará destructivo.Teniendo en mente los dos puntos anteriores, pregúntate: ¿por qué no sería seguro llamar a
MessageBox.Show
desde un hilo que no sea GUI? Se crea y muestra unForm
completamente separado; sus propiedades no interactúan de ninguna manera con ningún otro objeto GUI existente; de hecho, no se puede acceder a él de ninguna manera , excepto uno: desde el subproceso que llama, que accede a su propiedadDialogResult
(y solo eso a través del valor de retorno del métodoShow
).
Moviéndose a lo largo. Conrad Albrecht dijo:
... dada la afirmación de que Show () configura su propia bomba de mensajes en el tema de referencia de Dan, (que no se confirmó, pero que no puedo refutar) ...
Este es un punto totalmente justo (aunque personalmente tengo a Jared Par con la suficiente estima de que, en general, no estaría dispuesto a dudar de lo que dice). En cualquier caso, un vistazo al método MessageBox.Show
través de Reflector revela este fragmento de código:
Application.BeginModalMessageLoop();
try
{
result = Win32ToDialogResult(SafeNativeMethods.MessageBox(new HandleRef(owner, zero), text, caption, type));
}
finally
{
Application.EndModalMessageLoop();
UnsafeNativeMethods.ThemingScope.Deactivate(userCookie);
}
Un vistazo adicional al método Application.BeginModalMessageLoop
revela esto:
ThreadContext.FromCurrent().BeginModalMessageLoop(null);
Y este ThreadContext.FromCurrent
, a su vez:
// [Reflector shows that currentThreadContext is a ThreadStatic member. -Dan]
if (currentThreadContext == null)
{
currentThreadContext = new Application.ThreadContext();
}
return currentThreadContext;
No sé lo suficiente sobre estas construcciones de Windows de nivel inferior para comprender completamente este código, pero me parece que esto es evidencia de lo que Jared estaba diciendo exactamente en la respuesta a la que hice referencia en mi comentario anterior (para lectores curiosos: MessageBox. ¿Mostrar () automáticamente al hilo de la interfaz de usuario? ).
Así que sí. Estoy totalmente de acuerdo con MUG4N en este caso.
(Si alguien puede argumentar de manera convincente que todavía estoy equivocado aquí, por favor, hable. Aunque creo que he defendido bastante bien por qué creo que MUG4N tiene razón, obviamente no estoy 100% seguro).
Pregunta original
A menudo, solo desea notificar al usuario que algo ha ocurrido, pero realmente no hay necesidad de ninguna entrada de ellos. En este escenario común, a veces veo un código como este:
MessageBox.Show("Something has occurred", "Something", MessageBoxButtons.OK);
Este código, como todos sabemos, hace que aparezca una pequeña ventana emergente con solo un botón Aceptar . Ahora aquí está la cosa: este código de bloques (el hilo de la interfaz de usuario). Pero en la gran mayoría de los casos, me parece que, si solo tiene un botón Aceptar , hay muy poca necesidad de bloquear. (¿No es el propósito del bloqueo normalmente recibir alguna información del usuario? Y si la única opción del usuario es "OK", en este caso típico, ¿no es el bloqueo bastante inútil?)
Obviamente, solo podría escribir mi propia pequeña forma que hace básicamente lo que hace MessageBox.Show
, excepto que no devuelve nada (sin DialogResult
) y no se bloquea. Pero me preguntaba si ya existía algo como esto que no conocía.
Debe usar subprocesos múltiples para realizar esta tarea en la que un subproceso (el subproceso principal) realizará el procesamiento y el otro subproceso se usará para mostrar el cuadro de mensaje.
Es una vieja pregunta, pero nunca theles ...
1) Importar IWshShell (''Modelo de objeto de host de Windows Script'')
Dim wsh As New IWshRuntimeLibrary.WshShell wsh.Popup (String.Concat (Me.GetType.FullName, vbCrLf, _ Application.ExecutablePath), 0.75, "Title", MessageBoxButtons.OKCancel Or MessageBoxIcon.Question)
Jens ...
Lo que intentaría es llamar directamente a la función MessageBox desde la API de Win32, como:
using System.Runtime.InteropServices;
[DllImport("User32.dll")]
public static extern int MessageBox(int h, string m, string c, int type);
Intente usar un identificador nulo y el tipo APPLMODAL. Eso puede funcionar.