2012-10-05 3 views
5

Wie ich kürzlich zu meinen Kosten entdeckte, kann ein await, wenn es keinen Synchronisierungskontext gibt, den Code nach dem Warten auf einen anderen Thread führen.Wie kann ich die Fortsetzung nach einem Warten auf den gleichen Thread ausführen?

Ich habe derzeit Probleme mit seltsamen Verhalten in einem VSTO Office-Add-in, was ich denke, ist möglicherweise ein Ergebnis dieses Verhaltens. Bei der Verarbeitung von Ereignissen, die von der Office-Anwendung ausgelöst werden, ist kein Synchronisierungskontext vorhanden (es sei denn, ich erstelle ein Formular, das einen Synchronisationskontext erstellt).

Meine Frage ist, ob das Erstellen eines Formulars der beste/effizienteste Weg ist, um sicherzustellen, dass ich einen Synchronisationskontext habe oder ob es einen einfacheren Weg dafür gibt.

+0

Wäre es nicht einfacher, in diesem Fall nicht 'erwarten' zu verwenden? Wenn die von Ihnen verwendete API nur asynchron ist, können Sie dies erreichen, indem Sie 'Task'' Result' oder 'Wait()' verwenden. – svick

+0

@svick: Ich denke, was du sagst ist, dass, wenn ich möchte, dass die warten auf den gleichen Thread zurückkommen, dann ist das effektiv "synchrone" Verhalten. Hmmm ... ja, ich denke schon. *Seufzer*. Ich bin ein bisschen verloren mit diesem Zeug, um ehrlich zu sein. –

Antwort

5

Office-Anwendungen rufen ihre Ereignisse in einem STA-Kontext auf, bieten jedoch keine geeigneten SynchronizationContext.

Der einfachste Weg, dies zu umgehen, ist in SynchronizationContext Odds and Ends auf meinem Blog erklärt, wo ich ein paar verschiedene Dinge kurz beschreiben, die ich während für meinen Artikel forschen gefunden, aber nur waren nicht wichtig genug zu schließen. Um dieses Problem zu beheben, zu Beginn jeder Veranstaltung, dies tun:

SynchronizationContext.SetSynchronizationContext(
    new WindowsFormsSynchronizationContext()); 

Alle await s danach auf dem STA-Thread wieder aufnehmen sollte.

+0

Hinweis für alle, die daran denken - siehe auch http://stackoverflow.com/q/12898569/98422 –

3

Sie möchten vielleicht this article auschecken, die beschreibt, wie Sie einen SynchronizationContext ohne eine Nachrichtenpumpe einrichten. Beachten Sie, dass dies nur nützlich ist, wenn Sie andere Arbeiten erwarten, die Sie erwarten (mehrere Queues in die Warteschlange stellen). Wenn Sie immer nur eine Sache auf einmal erwarten, kann Ihr Code genauso gut synchron laufen, da Sie t haben Sie noch etwas anderes mit Ihrer Leerlaufzeit zu tun, wie zum Beispiel eine Nachrichtenpumpe.

Verwandte Themen