2010-08-16 33 views
5

En mi Windows tengo un TextBox que me gusta actualizar (propiedad del texto) desde otro hilo. Al hacerlo, obtengo la InvalidOperationException (ver título). He encontrado diferentes enlaces en google explicando esto, pero todavía no puedo hacer que funcione.WPF System.InvalidOperationException: el hilo de llamada no puede acceder a este objeto porque lo posee un hilo diferente

Lo que he intentado es la siguiente:

código

Window1:

private static Window1 _myWindow; 
private MessageQueueTemplate _messageQueueTemplate; 
private const string LocalTemplateName = "LocalExamSessionAccessCodeMessageQueueTemplate"; 
private const string RemoteTemplateName = "RemoteExamSessionAccessCodeMessageQueueTemplate"; 

... 
public Window1() 
{ 
    InitializeComponent(); 
    _myWindow = this; 
} 

public static Window1 MyWindow 
{ 
    get 
    { 
     return _myWindow; 
    } 
} 

public void LogText(string text) 
{ 
    informationTextBox.Text += text + Environment.NewLine; 
} 
... 

En otra clase (en realidad un adaptador spring.NET Listener, se escucha una cierta cola, se inició en otro hilo).

var thread = new Thread(
    new ThreadStart(
     delegate() 
      { 
       Window1.MyWindow.Dispatcher.Invoke(
        System.Windows.Threading.DispatcherPriority.Normal, 
        new Action(
         delegate() 
          { 
           Window1.MyWindow.LogText(text); 
          } 
         )); 
      } 
     )); 

no tira un error, pero el texto en el método LogText en Window1 no se activa, por lo que el texto no se actualiza.

Básicamente, quiero actualizar este componente TextBox de otra clase que se ejecuta en otro hilo.

Respuesta

6
Window1.MyWindow.informationTextBox.Dispatcher.Invoke(
    DispatcherPriority.Normal, 
    new Action(() => Window1.MyWindow.informationTextBox.Text += value)); 
3

Bueno, usando Dispatcher.Invoke o BeginInvoke es definitivamente el camino a seguir, pero que realmente no han mostrado mucho código que no sea la creación de un hilo - por ejemplo, usted no ha comenzado el hilo en su segundo bloque de código.

Si coloca el código Dispatcher.Invoke en el lugar donde anteriormente obtenía un InvalidOperationException, debería estar bien.

+0

¡Admiro tu paciencia! ¡Creo que es la vez número billón que se ha pedido! – Manfred

+0

Bueno, John, lo sé, y he buscado esas otras preguntas pero no he encontrado la respuesta que estaba buscando. Podría ir y leer numerosos enlaces sobre despachadores e hilos, pero la verdad es que no tengo tiempo para eso. Traté de hacer lo que otros sugirieron, pero no funciona. @Jon Skeet: El código que inicia el hilo de mi segundo bloque de código está en los ensamblajes de Spring.NET. Crean hilos que escuchan una cola msmq y activan un método en una clase adaptadora personalizada. En esta clase, quiero actualizar un TextBox. –

+2

@Lieven: Sería realmente, realmente útil si crearas un programa corto pero completo que demuestra el problema. Es posible que al hacer eso, encuentre el problema usted mismo. El programa completo no necesita tratar con Spring, etc. Simplemente cree un hilo que actualice regularmente la interfaz de usuario, o algo así. Usar 'Dispatcher' * es * la respuesta aquí, pero no podemos decir qué estás haciendo mal dentro del código que has mostrado. –

0

para WPF, creo que este constructo:

BackgroundWorker bw = new BackgroundWorker(); 
    bw.DoWork += (s, e) => 
    { 
    }; 
    bw.RunWorkerCompleted += (s, e) => 
    { 
    }; 
    bw.RunWorkerAsync(); 

a ser el más útil. El bloque RunWorkerCompleted normalmente actualizará un ObservableCollection o lanzará un RaisePropertyChangedEvent.

Cuestiones relacionadas