Estoy convirtiendo un analizador de chat para un juego que juego que escribí en C# winforms en wpf, principalmente para obtener un mejor manejo en MVVM y wpf. Aquí está un funcionamiento abajo de la forma en que he establecido mi proyecto¿Es incorrecto utilizar el despachador dentro de mi ViewModel?
Ver: Por ahora es sólo un simple ListBox con ItemSource con destino a mis ViewModels colección de chat observables
Modelo: que tienen múltiples personajes que pueden iniciar sesión al mismo tiempo y cada personaje tiene una clase de chat. La clase de chat inicia un trabajador de segundo plano que capta y la siguiente línea de chat del juego y dispara un evento llamado IncomingChat con esta línea.
public event Action<Game.ChatLine> IncomingChat;
estoy usando un trabajador de fondo para desencadenar un evento en mis backgroundworkers caso progresschaged porque cuando yo estaba usando un temporizador seguí recibiendo una cuestión de roscado. Al principio corregí esto cambiando mi Timer a DispatchTimer, pero no me pareció correcto tener un DispatchTimer en mi modelo.
ViewModel: Como tengo varios caracteres, estoy creando varios modelos de ChatView. Paso un personaje en el constructor ChatViewModels y me suscribo al evento Chat. Creé una ObservableColleciton para contener mis líneas de chat cuando se recibe este evento. Ahora recibo un problema de subprocesamiento en mi viewModel al intentar agregar la línea que recibo de mi evento de chat a mi colección observable.
llegué alrededor de esto haciendo mis ViewModels controlador de eventos de chat entrante parezca tan
public ObservableCollection<Game.ChatLine) Chat {get; private set;}
void Chat_Incoming(Game.ChatLine line)
{
App.Current.Dispatcher.Invoke(new Action(delegate
{
Chat.Add(line)
}), null);
}
Esto no se siente bien para mí, sin embargo. Aunque funciona, el uso de Dispatcher en mi modelo de vista como este parece fuera de lugar para mí.
El SynchronizationContext es el que se debe usar. Este patrón se usa en todo momento, por lo que el código de enhebrado se puede escribir genéricamente y seguir estando disponible ya sea que esté haciendo winforms, wcf, wpf, wf o ASP.NET (estoy asumiendo el último). – Will
@Will: El OP estaba usando WPF (en el texto), pero sí, esto funcionará para cualquier técnico, por eso me gusta tanto ... –
+1, no me di cuenta de que TPL tenía un planificador que podría usar SynchronizationContext. Mi código todavía usa SynchronizationContext Post/Send directamente. –