2010-06-05 18 views
12

primero Tengo que decir que soy novato con WPF y C#. Aplicación: Crear Mandelbrot Imagen (GUI) Mi despachador funciona perfectamente este caso:WPF Dispatcher {"El hilo que llama no puede acceder a este objeto porque lo posee un hilo diferente."}

private void progressBarRefresh(){ 

     while ((con.Progress) < 99) 
     { 
      progressBar1.Dispatcher.Invoke(DispatcherPriority.Send, new Action(delegate 
       { 
        progressBar1.Value = con.Progress; 
       } 
      )); 
     } 
    } 

consigo el mensaje (título) cuando Tring para hacer esto con el código de abajo:

bmp = BitmapSource.Create(width, height, 96, 96, pf, null, rawImage, stride); 

this.Dispatcher.Invoke(DispatcherPriority.Send, new Action(delegate 
      {      
       img.Source = bmp; 
       ViewBox.Child = img; //vllt am schluss 
      } 
     )); 

I trataré de explicar cómo funciona mi programa. Creé un nuevo subproceso (porque la GUI no responde) para el cálculo de los píxeles y los colores. En este subproceso (método) estoy usando el despachador para actualizar mi imagen en el ViewBox después de que los cálculos estén listos.

Cuando no coloco el cálculo en un subproceso separado, entonces puedo actualizar o crear mi imagen.

Respuesta

2

Está creando el mapa de bits (bmp) en su subproceso de trabajador (?) Y luego lo pasa al subproceso de interfaz de usuario; esto está fallando.

Debe crear la imagen en el hilo de la interfaz de usuario. Probablemente necesite alguna forma de referenciar qué imagen desea mostrar y pasar esa información a la interfaz de usuario.

+1

No es necesario crear la imagen en el hilo de la interfaz de usuario. Simplemente no puede usarlo de un hilo mientras está siendo modificado en otro (y .NET asume que a menos que lo marque * frozen *, se modificará de nuevo). –

2

También es posible usar un mecanismo de cola para pasar mensajes entre las roscas. Después de todo, así es como funciona la arquitectura de Windows. Eso es lo que hace el despachador. Está pasando una referencia al delegado, que no es propiedad del subproceso de WPF.

Así que sí, que tienen la idea básica, pero hay que pasar realmente el mapa de bits en el otro hilo mediante el uso de Action<T>(T object), o en su caso:

Dispatcher.Invoke(DispatcherPriority.Send, new Action<Bitmap>(delegate(Bitmap img) { 
    do things here... 
}), bmp); 
+1

No hará la diferencia, todavía está compartiendo el objeto al que se hace referencia. –

22

En caso de que el objeto debe ser compartido entre diferentes subprocesos, entonces siempre crea ese objeto en el subproceso de la interfaz de usuario. Más tarde, cuando desee acceder al objeto, puede verificar si tiene acceso al objeto. Si no tiene acceso, vuelva a invocar la función con acceso de subproceso de interfaz de usuario. código de ejemplo a continuación:

private void YourMethod() 
    { 
     if (Application.Current.Dispatcher.CheckAccess()) 
     { 
      // do whatever you want to do with shared object. 
     } 
     else 
     { 
      //Other wise re-invoke the method with UI thread access 
      Application.Current.Dispatcher.Invoke(new System.Action(() => YourMethod())); 
     } 
    } 
2

Cuando se obtiene una Dispatcher que presentamos lo mejor uno diferente para cada subproceso diferente.

this.Dispatcher podría estar otorgándole otro Dispatcher, no el UI, por lo que se obtiene ese error.

En cambio, intente utilizar Application.Current.Dispatcher, esto siempre devolverá el despachador del subproceso de interfaz de usuario.

El mismo error puede ocurrir si utiliza Dispatcher.CurrentDispatcher desde otra secuencia, por supuesto.

Cuestiones relacionadas