Ich habe eine WinForms-App und ich benötige Code, der auf dem UI-Thread ausgeführt werden muss. Der Code nach dem await
wird jedoch auf einem anderen Thread ausgeführt.
Ich habe auch versucht, ConfigureAwait(true)
explizit hinzuzufügen, aber das macht keinen Unterschied. Mein Verständnis war, dass, wenn ich ConfigureAwait(false)
weglasse, sollte die Fortsetzung auf dem ursprünglichen Thread laufen. Ist das in einigen Situationen falsch?
Ich habe auch bemerkt, dass, wenn ich der Sammlung vor der Wartezeit ein Steuerelement hinzufüge, die Fortsetzung magisch auf dem richtigen Thread läuft.
%Vor%Meine Frage ist:
Als Referenz sind hier die wichtigen Teile von DoSomethingAsync
. Es sendet eine HTTP-Anfrage mit RestSharp.
Es scheint, dass mit OnHandleCreated
etwas Seltsames passiert. Meine Lösung war, stattdessen OnLoad
zu verwenden. Ich bin ziemlich glücklich mit dieser Lösung, weil es wirklich keinen Grund gibt, OnHandleCreated
in meiner Situation zu verwenden.
Ich bin immer noch neugierig, warum das passiert, also wenn jemand weiß, fühlen Sie sich frei, eine andere Antwort zu posten.
Bearbeiten:
Ich habe das echte Problem gefunden: Es stellte sich heraus, dass ich Form.ShowDialog()
nach einem ConfigureAwait(false)
aufgerufen habe. Daher wurde das Formular im UI-Thread erstellt, aber ich habe ShowDialog
in einem Thread ohne Benutzeroberfläche aufgerufen. Ich bin überrascht, dass das überhaupt funktioniert hat.
Ich habe ConfigureAwait(false)
entfernt, sodass jetzt ShowDialog
im UI-Thread aufgerufen wird.
Mein Verständnis war, dass wenn ich ConfigureAwait (false) weglasse, sollte die Fortsetzung auf dem ursprünglichen Thread laufen. Ist das in einigen Situationen falsch?
Was tatsächlich passiert, ist, dass await
standardmäßig den aktuellen Kontext erfasst und diesen Kontext verwendet, um die Methode async
wieder aufzunehmen. Dieser Kontext ist SynchronizationContext.Current
, außer es ist null
, in diesem Fall ist es TaskScheduler.Current
(normalerweise der Thread-Pool-Kontext). Die meiste Zeit hat der UI-Thread eine UI SynchronizationContext
- im Fall von WinForms eine Instanz von WinFormsSynchronizationContext
.
Ich habe auch bemerkt, dass, wenn ich der Sammlung vor der Wartezeit ein Steuerelement hinzufüge, die Fortsetzung magisch auf dem richtigen Thread läuft.
Kein Thread beginnt automatisch mit einem SynchronizationContext
. Die WinForms SynchronizationContext
wird auf Anforderung installiert, wenn das erste Steuerelement erstellt wird. Aus diesem Grund sehen Sie nach dem Erstellen eines Steuerelements die Fortsetzung in einem Benutzeroberflächenthread.
Da der Wechsel zu OnLoad
eine praktikable Lösung ist, empfehle ich Ihnen, einfach mitzugehen. Die einzige andere Option (die Fortsetzung auf dem UI-Thread vor dem Erstellen eines Steuerelements) besteht darin, ein Steuerelement vor dem ersten await
manuell zu erstellen.
Tags und Links .net c# winforms async-await