martes, 31 de marzo de 2009

WPF y threading

Tras muchos años de desarrollo prácticamente exclusivo para entorno web, el proyecto basado en Surface en el que estoy trabajando actualmente ha hecho que algunas de las palabras que tenía archivadas en las zonas más oscuras de mi cerebro hayan tenido que ser recuperadas. Una de ellas era threading.

El elemento a desarrollar era teóricamente sencillo. Un flujo en segundo plano que actualizase el mapa de Virtual Earth que tenía en primer plano. Lo primero que tenía que hacer es ejecutar un flujo más o menos de la siguiente manera:

Threading.MapController controller = new Threading.MapController();
controller.Container = this;
App.ControllerThread = new Thread(new ThreadStart(controller.Run));
App.ControllerThread.Start();

Después, a la hora de implementar el método Run de la clase MapController, lo primero que se me podía ocurrir era algo similar a lo siguiente:

public void Run()
{
   while (true)
   {
      Thread.Sleep(100);
      this.Container.RefreshMap();
   }
}

Independientemente de la utilidad de este flujo y de las maneras de implementarlo me llamó la atención una excepción que saltaba siempre:

The calling thread cannot access this object because a different thread owns it.

Al parecer, desarrollando sobre WPF no se puede acceder a objetos que están controlados por un flujo distinto al actual. En este caso, desde el flujo que hemos lanzado en segundo plano se intenta acceder al objeto contenedor del mapa que, obviamente, está controlado por el flujo principal.

Tras un poco de investigación descubrí una manera muy simple de hacer lo que pretendía hacer. Aquí os dejo el trozo de código que resolvió el entuerto.

public void Run()
{
   while (true)
   {
      Thread.Sleep(100);
      this.Container.Dispatcher.Invoke(
         System.Windows.Threading.DispatcherPriority.Normal,
         new Action(delegate()         
            {
                this.Container.RefreshMap();         
            }
      ));  
   }
}

La clave está en utilizar el Dispatcher que tenemos disponible en cada uno de los controles WPF para ejecutar el código que accede a dicho objeto.

Related Posts:

  • Salón Admira en ValladolidLos días 28, 29 y 30 de Mayo de 2009 se ha celebrado en el Recinto Ferial de Valladolid el Salón Admira con el fin de ser una exposición de productos y servicios para la innovación y modernización de las administraciones públ… Read More
  • Surface SDK 1.0 SP1 releasedLa semana pasada se anunció la disponibilidad del SP1 del Surface SDK 1.0. La manera de obtenerlo es solicitarlo via email a Microsoft, a través del sitio web de Surface, que te lo hace llegar en un plazo de 2-3 semanas en so… Read More
  • Instalado el Service Pack 1 del runtime de Surface La pasada semana recibí, por fin, el esperado service pack 1 del runtime de Surface. Los cambios introducidos por Microsoft en este nuevo paquete hacen referencia a: Mejoras a nivel de desarrollo Mejoras en la interfaz de … Read More
  • LRG Solutions Forum 2009La semana pasada acudí por primera vez al evento Local and Regional Government Solutions Forum para presentar, junto con algunos compañeros de Spenta Consulting, 3 de los productos en los que he estado trabajando en los últim… Read More
  • ¿La primera Surface en Catalunya?Hoy me han dicho que se ha ofrecido en televisión la noticia de que Raona ha presentado en sociedad la primera unidad de Microsoft Surface en Catalunya. La noticia me ha sorprendido, teniendo en cuenta que llevo trabajando de… Read More

0 comentarios: