2010-02-17 19 views
5

Tengo una aplicación de formulario de Windows escrita en C# en la que utilizo un FileSystemWatcher para supervisar una carpeta de archivos nuevos y luego realizar algún procesamiento en ellos. Mi aplicación está diseñada para ejecutarse en la bandeja del sistema y, por lo tanto, no crea ninguna instancia en el inicio. El problema es que el evento Creado está activando un hilo separado y cuando intento crear una instancia de un formulario en el evento Creado obtengo una excepción ThreadStateException que indica que debo estar ejecutándome en SingleThreadApartment. Creo que necesito establecer la propiedad FileSystemWatcher.SynchronizingObject pero no sé qué usar ya que no hay un formulario principal en mi aplicación.FileSystemWatcher.SynchronizingObject sin formulario

Respuesta

4

Tendrá que llamar a Application.Run() en su método Main() para obtener la maquinaria de sincronización de Windows Forms en su lugar para que FileSystemWatcher pueda coordinar correctamente la llamada al hilo principal. El problema que tendrá entonces es que la forma principal se hará visible. Corrija eso pegando este código en la clase:

protected override void SetVisibleCore(bool value) { 
     if (!this.IsHandleCreated) { 
      this.CreateHandle(); 
      value = false; 
     } 
     base.SetVisibleCore(value); 
    } 

No hay restricciones sobre cómo se ve su formulario si lo hace.

+0

Funcionó como un amuleto. La forma oculta ni siquiera parpadea en la pantalla. – AdmSteck

1

La forma más simple de hacer esto es hacer una forma oculta y pasarla a Application.Run.

Puede establecer la propiedad SynchronizingObject en el formulario oculto.

Para asegurarse de que es un formulario oculto, establezca las propiedades ControlBox y ShowInTaskbar en false.

+0

En realidad, dado que 'ISynchronizeInvoke' es implementado por' Control', me imagino que sería suficiente crear una instancia 'Control' y asignarla a' SynchronizingObject'. No lo intenté, pero podría funcionar. –

+0

@ FredrikMörk Improbable; algo necesita hacer un ciclo en el hilo principal que realmente realizará la invocación solicitada. Application.Run hace eso. –

2

No necesita pasar ningún formulario al Application.Run en absoluto. Entonces puede ahorrar tener que perder el tiempo con la visibilidad del formulario. Sólo hacer esto:

var InvokerForm = new Form(); 
var dummy = InvokerForm.Handle; // force handle creation 
Application.Run(); 

Sólo una gotcha de allí - la creación de formularios mango debe ser forzado por acceder a él de una vez.

Cuestiones relacionadas