2010-02-17 4 views
5

Ich habe eine Windows-Formularanwendung geschrieben in C#, in der ich einen FileSystemWatcher verwenden, um einen Ordner für neue Dateien zu überwachen und dann einige Verarbeitung für sie durchzuführen. Meine Anwendung ist so konzipiert, dass sie in der Taskleiste ausgeführt wird und daher beim Start keine Formulare instanziiert. Das Problem ist, dass das Created-Ereignis in einem separaten Thread ausgelöst wird, und wenn ich versuche, eine Instanz eines Formulars im Created-Ereignis zu erstellen, erhalte ich eine ThreadStateException, die besagt, dass ich in SingleThreadApartment ausgeführt werden muss. Ich denke, ich muss die FileSystemWatcher.SynchronizingObject Eigenschaft festlegen, weiß aber nicht, was zu verwenden ist, da in meiner Anwendung kein Hauptformular vorhanden ist.FileSystemWatcher.SynchronizingObject ohne ein Formular

Antwort

4

Sie müssen Application.Run() in Ihrer Main() -Methode aufrufen, um die Windows Forms-Synchronisierungsmaschinerie in Position zu bringen, damit FileSystemWatcher den Aufruf an den Hauptthread ordnungsgemäß marshallen kann. Das Problem, das Sie dann haben, ist, dass das Hauptformular sichtbar wird. Korrigieren Sie das, indem Sie diesen Code in die Klasse einfügen:

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

Es gibt keine Einschränkungen, wie Ihr Formular aussieht, wenn Sie dies tun.

+0

Arbeitete wie ein Charme. Versteckte Form blinkt nicht einmal auf dem Bildschirm. – AdmSteck

1

Der einfachste Weg, dies zu tun ist, ein verstecktes Formular zu machen und es an Application.Run zu übergeben.

Sie können dann die SynchronizingObject-Eigenschaft auf die ausgeblendete Form festlegen.

Um sicherzustellen, dass es sich um ein verborgenes Formular handelt, legen Sie die Eigenschaften ControlBox und ShowInTaskbar auf false fest.

+0

Da "ISynchronizeInvoke" von 'Control' implementiert wird, würde ich mir vorstellen, dass es ausreichend wäre, eine' Control'-Instanz zu erstellen und sie 'SynchronizingObject' zuzuweisen. Habe es nicht versucht, aber es könnte funktionieren. –

+0

@ FredrikMörk Unwahrscheinlich; Etwas muss eine Schleife auf dem Haupt-Thread drehen, die den angeforderten Aufruf tatsächlich ausführt. Application.Run macht das. –

2

Sie müssen keine Formulare an Application.Run überhaupt übergeben. Dann können Sie sparen, wenn Sie sich mit der Formularsichtbarkeit herumschlagen müssen. Genau dies tun:

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

nur Gotcha man dort - die Form Griff Schöpfung es durch den Zugriff auf einmal gezwungen zu werden braucht.