dispatcher c# example
Usando el despachador de C# (2)
Estoy creando un cliente de chat y no estoy 100% seguro de cómo usar el dispatcher
. Entonces la pregunta es que tengo un método como tal:
public void LostConnection()
{
myGUI.chatBox.AppendText("Lost connection to room: "+ myGUI.UsernameText.ToString() + "/r/n");
}
¿Debo guardar la declaración dentro de (myGUI.chatBox... )
con un Dispatcher.Invoke
? Aprecio cualquier ayuda.
Algo como esto (fuera de mi cabeza) debería funcionar:
public void LostConnection()
{
myGUI.Invoke
((MethodInvoker)delegate
{
myGUI.chatBox.AppendText("Lost connection to room: "+ myGUI.UsernameText.ToString() + "/r/n");
});
}
Su aplicación tiene un subproceso de la interfaz de usuario principal (generalmente ManagedThreadId==1
). Por lo general, en una aplicación de chat, sus eventos aparecerán en otros subprocesos (ya sean hilos de escucha de socket dedicados o subprocesos de agrupación de hilos de código de escucha). Si desea actualizar la interfaz de usuario de un evento que obtiene un tirón en algún otro hilo, debe usar el distribuidor. Una prueba útil aquí es el método Dispatcher.CheckAccess()
que devuelve verdadero si el código está en el subproceso de la interfaz de usuario y falso si en algún otro subproceso. Una llamada típica se ve algo así como:
using System.Windows.Threading; // For Dispatcher.
if (Application.Current.Dispatcher.CheckAccess()) {
network_links.Add(new NetworkLinkVM(link, start_node, end_node));
}
else {
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(()=>{
network_links.Add(new NetworkLinkVM(link, start_node, end_node));
}));
}
Si estás en la ventana principal puedes usar:
Dispatcher.BeginInvoke(...
Si está en otro contexto, por ejemplo, un modelo de vista, use:
Application.Current.Dispatcher.BeginInvoke(
Invoke vs BeginInvoke
Use Invoke
si desea que el subproceso actual espere hasta que el subproceso de la interfaz de usuario haya procesado el código de envío o BeginInvoke
si desea que el subproceso actual continúe sin esperar a que se complete la operación en el subproceso de la interfaz de usuario.
MessageBox, Dispatchers e Invoke / BeginInvoke:
Dispatcher.Invoke
bloqueará su hilo hasta que se descarte el MessageBox.
Dispatcher.BeginInvoke
permitirá que su código de hilo continúe ejecutándose mientras que el hilo de la interfaz de usuario se bloqueará en la llamada de MessageBox hasta que se cierre.
CurrentDispatcher vs Current.Dispatcher!
Tenga en cuenta que Dispatcher.CurrentDispatcher
como entiendo de esto es que devolverá un Dispatcher para el subproceso actual, no el subproceso de la interfaz de usuario. En general, está interesado en el despachador en el subproceso de la interfaz de usuario: Application.Current.Dispatcher
siempre devuelve esto.
Nota adicional:
Si encuentra que tiene que revisar CheckAccess del despachador a menudo, un método útil de ayuda es:
public void DispatchIfNecessary(Action action) {
if (!Dispatcher.CheckAccess())
Dispatcher.Invoke(action);
else
action.Invoke();
}
Que se puede llamar como:
DispatchIfNecessary(() => {
network_links.Add(new NetworkLinkVM(link, start_node, end_node));
});