2009-08-11 10 views
6

Tengo un hilo que llama a un objeto que obtiene algunas cosas de Internet. Cuando este objeto se completa con toda la información requerida, se genera un evento con un objeto con toda la información. El evento es consumido por el controlador que ha iniciado el hilo.WPF hilo y GUI cómo acceder a objetos de hilo diferente?

El objeto devuelto del evento se agrega a una colección enlazada a la GUI mediante un enfoque de Ver modelo.

El problema es que no puedo usar CheckAccess con el enlace ... ¿cómo puedo solucionar el problema de usar Objeto que se ha creado a partir de otro hilo del principal?

El error que recibo cuando agrego el objeto a la colección de la rosca principal es:

Este tipo de CollectionView no admite cambios en su SourceCollection de un hilo diferentes de la rosca Dispatcher.

Esta el controlador:

public class WebPingerController 
{ 
    private IAllQueriesViewModel queriesViewModel; 

    private PingerConfiguration configuration; 

    private Pinger ping; 

    private Thread threadPing; 

    public WebPingerController(PingerConfiguration configuration, IAllQueriesViewModel queriesViewModel) 
    { 
     this.queriesViewModel = queriesViewModel; 
     this.configuration = configuration; 
     this.ping = new Pinger(configuration.UrlToPing); 
     this.ping.EventPingDone += new delPingerDone(ping_EventPingDone); 
     this.threadPing = new Thread(new ThreadStart(this.ThreadedStart)); 
    } 


    void ping_EventPingDone(object sender, QueryStatisticInformation info) 
    { 
     queriesViewModel.AddQuery(info);//ERROR HAPPEN HERE 
    } 

    public void Start() 
    { 
     this.threadPing.Start(); 
    } 

    public void Stop() 
    { 
     try 
     { 
      this.threadPing.Abort(); 
     } 
     catch (Exception e) 
     { 

     } 
    } 

    private void ThreadedStart() 
    { 
     while (this.threadPing.IsAlive) 
     { 
      this.ping.Ping(); 
      Thread.Sleep(this.configuration.TimeBetweenPing); 
     } 
    } 
} 

Respuesta

6

he encontrado la solución sobre este blog.

En lugar de simplemente llamar a la colección para agregar el objeto de la rosca.

queriesViewModel.AddQuery(info); 

I tienen que pasar el hilo principal al controlador y utilizar el despachador. La respuesta de la Guardia estaba muy cerca.

public delegate void MethodInvoker(); 
    void ping_EventPingDone(object sender, QueryStatisticInformation info) 
    { 
     if (UIThread != null) 
     { 

      Dispatcher.FromThread(UIThread).Invoke((MethodInvoker)delegate 
      { 
       queriesViewModel.AddQuery(info); 
      } 
      , null); 
     } 
     else 
     { 
      queriesViewModel.AddQuery(info); 
     } 
    } 
+1

¿Puedes publicar la definición de UIThread en este contexto, por favor? Gracias. No sé en qué sustituirlo en mi código – Para

+1

La misma pregunta. ¿Qué significa UIThread exactamente? – zero51

+0

Debe ser una subclase de 'System.Windows.Threading.DispatcherObject'. – Jalal

3

podría ser una solución para inicializar el objeto en el hilo principal?

MyObject obj; 

this.Dispatcher.Invoke((Action)delegate { obj = new MyObject() }); 

Editar: En una segunda lectura a través, esto probablemente no es una solución dada su modelo. ¿Estás recibiendo un error de tiempo de ejecución tal como está? Si el objeto que está devolviendo es suyo, asegurarse de que el objeto esté protegido contra subprocesos podría hacer que CheckAccess no sea necesario.

+0

Este tipo de CollectionView no admite cambios en su SourceCollection de un hilo diferente del hilo Dispatcher. –

Cuestiones relacionadas