El enfoque común es tener una propiedad Dispatcher en su modelo de vista (probablemente en una clase base para todos los modelos de vista) que se puede inyectar fuera. Está bien tenerlo en un modelo de vista porque el modelo de vista DEBERÍA tener en cuenta los conceptos de la interfaz de usuario, pero no debería tener en cuenta una vista en particular (diseño, controles, etc.) y ciertamente no debería tener una referencia a la vista.
Lo que puede hacer es facilitar el envío de su código al hilo Dispatcher creando un ayudante o un servicio que abstraerá el despachador. Por ejemplo, puede crear un ayudante así:
public class AsyncHelper
{
public static void EnsureUIThread(Action action)
{
if (Application.Current != null && !Application.Current.Dispatcher.CheckAccess())
{
Application.Current.Dispatcher.BeginInvoke(action, DispatcherPriority.Background);
}
else
{
action();
}
}
}
Y cada vez que necesita para actualizar su colección observable, que se envuelva código en ese método de ayuda:
AsyncHelper.EnsureUIThread(() =>
{
// Update you observable collections here
});
O bien, puede ir más allá y use AOP (por ejemplo, PostSharp) para especificar declarativamente (utilizando atributos) que un método debe ejecutarse en el hilo de la interfaz de usuario.
Y, por último, tenga en cuenta que debe enviar solo actualizaciones de la colección al hilo de la interfaz de usuario. Las propiedades habituales se pueden actualizar de forma segura desde un hilo de fondo. Las actualizaciones se enviarán al subproceso de interfaz de usuario automáticamente mediante el mecanismo de enlace. Probablemente en futuras versiones de WPF también se admitirán actualizaciones de una colección de un hilo de fondo.
1 debido a que hizo referencia maravilloso video en MVVM de Jason :). Creo que votaré cada respuesta que contenga un enlace. No puedo hacer suficiente hincapié en lo bueno que es. Bueno, y tu respuesta es correcta. – Anvaka