Su aplicación tiene un hilo principal interfaz de usuario (por lo general ManagedThreadId==1
). Por lo general, en una aplicación de chat sus eventos aparecerán en otros hilos (ya sea hilos de escucha de socket dedicado o hilos de grupo de hilos desde el código de escucha). Si desea actualizar la interfaz de usuario de un evento que obtiene algún otro hilo, debe usar el despachador. Una prueba útil aquí es el método Dispatcher.CheckAccess()
que devuelve verdadero si el código está en el hilo de UI y falso si está en algún otro hilo. Una llamada típica se ve algo 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 se puede utilizar:
Dispatcher.BeginInvoke(...
Si estás en someother contexto por ejemplo, un modelo de vista a continuación, utilizar:
Application.Current.Dispatcher.BeginInvoke(
invocación vs BeginInvoke
uso Invoke
si desea que el hilo actual que esperar hasta que el hilo de interfaz de usuario ha procesado el código de envío o BeginInvoke
si desea que el hilo actual continúe sin esperar a que la operación finalice en el hilo de la interfaz de usuario.
de mensaje, despachadores e invocar/BeginInvoke:
Dispatcher.Invoke
bloqueará el hilo hasta que se desestimó el cuadro de mensaje.
Dispatcher.BeginInvoke
permitirá que su código de subproceso continúe ejecutándose mientras que el subproceso de la interfaz de usuario se bloqueará en la llamada de MessageBox hasta que se desestime.
CurrentDispatcher versus Current.Dispatcher!
Tenga en cuenta Dispatcher.CurrentDispatcher
ya que mi comprensión de esto es que devolverá un despachador para el hilo actual, no el hilo de la interfaz de usuario. Generalmente está interesado en el despachador en el hilo de la interfaz de usuario: Application.Current.Dispatcher
siempre lo devuelve.
Nota adicional:
Si usted está encontrando que está teniendo para comprobar despachador CheckAccess a menudo entonces un método de ayuda útil es:
public void DispatchIfNecessary(Action action) {
if (!Dispatcher.CheckAccess())
Dispatcher.Invoke(action);
else
action.Invoke();
}
que puede ser llamado como:
DispatchIfNecessary(() => {
network_links.Add(new NetworkLinkVM(link, start_node, end_node));
});
Eso Depende ... ¿En qué hilo se ejecuta ese método? Además, solo para estar seguro, estás usando WPF, ¿verdad? ('Dispatcher' solo funciona con eso.) – svick
¿Qué marco de interfaz de usuario está usando?(WinForms, WPF o SL) Existen diferencias entre ellos –
Sí, como sugiere svick, depende de si está tocando su UI desde otro hilo (asincrónicamente) – gideon