2010-10-05 9 views
5

Necesito "enviar" un fragmento de código de otro hilo (Interoperabilidad de Excel) al hilo de la interfaz de usuario para su ejecución. Lo normal sería utilizar Invoke en el Form, que implementa la interfaz ISynchronizeInvoke:Cómo usar ISynchronizeInvoke sin hacer referencia al Formulario

public class MyForm : Form 
{ 
    ... 
    private void Button_Click(object sender, EventArgs e) 
    { 
     SomeExcelWorkbook.OnBeforeClose += delegate(ref bool Cancel) 
     { 
      this.Invoke(someCode); 
     }; 
    } 
} 

Por desgracia, no es una capa de abstracción entre el código del formulario y el código que define el controlador de eventos, y no tiene una referencia a la forma en ese punto:

public void CodeExecutedByUIThread() 
{ 
    ISynchronizeInvoke sync; 
    SomeExcelWorkbook.OnBeforeClose += delegate(ref bool Cancel) 
    { 
     sync.Invoke(someCode); 
    }; 
} 

al entrar CodeExecutedByUIThread, que todavía están en el hilo de interfaz de usuario, así que en teoría todo lo necesario debería estar allí. Lamentablemente, el Form is the only class implementing that interface, ¿verdad?

¿Cómo puedo obtener un ISynchronizeInvoke desde dentro del hilo de UI? Aparentemente Thread.CurrentThread no lo proporciona ...

¿O hay una forma de obtener un SynchronizationContext? ¿Cómo recuperaría y usaría eso?

Actualización: Oh, veo, obtener el objeto SynchronizationContext es tan simple como SynchronizationContext.Current, que no necesita ninguna referencia a un formulario. Así que buscaré un poco más sobre cómo usar eso.

Respuesta

2

En general, creo que ninguno es posible.

Esto podría parecer una respuesta obvia, pero lo que usamos en este caso fue almacenar tanto el SynchronizationContext como la referencia al Formulario (como un ISynchronizeInvoke) en una clase estática al inicio de la aplicación.

MainForm main = new MainForm(); 
EnvironmentService.UI = main; 
EnvironmentService.UIContext = SynchronizationContext.Current; 
Application.Run(main); 
+0

Oh, veo, obtener el objeto SynchronizationContext parece bastante simple y, por lo tanto, debe funcionar incluso sin tener una referencia al formulario. – chiccodoro

+1

Tenga cuidado, ya que el uso de SynchronizationContext.Current en un subproceso secundario no obtendrá el contexto que desea, es por eso que recomiendo almacenarlo desde el hilo principal al inicio de la aplicación. – matiash

+0

Buen punto, he leído esa advertencia en un recurso web también mientras tanto. – chiccodoro

Cuestiones relacionadas