Ich habe ein scheinbar einfaches Problem: ein Popup, das mich Probleme verursacht sieht in einer abgespeckten Version wie folgt aus (die vollständige Version hat ein Spinner UserControl innerhalb des Border-Elements, aber das seltsame Verhalten ist das gleiche mit oder ohne). Das XAML ist dies:Popup wird nicht geöffnet
<Popup Name="PleaseWaitPopup" Placement="Center" IsOpen="False" StaysOpen="True" Opened="PopupOpened" Closed="PopupClosed">
<Border Width="200" Height="200" Padding="20" Background="#222">
<StackPanel Orientation="Vertical">
<TextBlock Name="WaitHeadTxt" Margin="0 0 0 36" Style="{StaticResource PopupHeadStyle}" VerticalAlignment="Top" FontSize="16"></TextBlock>
<Border Width="60" Height="60">
</Border>
</StackPanel>
</Border>
</Popup>
Alle Elemente (PopupOpened(), PopupClosed(), PopupHeadStyle) sind gut getestet und in vielen anderen Pop-ups im gleichen Projekt gut funktionieren.
Als Reaktion auf eine Benutzeraktion möchte ich dieses Popup öffnen, bevor Sie etwas starten, das einige Sekunden dauert (versuchen, ein Gerät über WLAN zu verbinden). Der Code ist wieder einfach:
PleaseWaitPopup.IsOpen = true;
try
{
wifiDeviceProvider = new PtpIpProvider();
DeviceManager.AddDevice(wifiDeviceProvider.Connect("192.168.1.1"));
}
catch (Exception ex)
{
...
}
In meinem Testfall, ich habe nicht ein externes Gerät anschließen, so dass der WiFi-Verbindungsversuch kommt zurück mit einem Timeout nach 10s. Das Popup öffnet sich immer erst NACH dem Timeout, was ich nicht bekomme. Zu diesem Zeitpunkt ist kein weiteres Popup geöffnet.
Ich versuchte dies mit anderen Action-Code (eine FTP-Übertragung anstelle der WiFi-Verbindung) - das Problem blieb, so ist es unwahrscheinlich, dass der WiFi-Verbindungscode damit zu tun hat. Versucht, Dinge asynchron zu machen, indem Sie das Popup oder die WiFi-Verbindung oder beide in einem separaten Thread über "this.Dispatcher.Invoke (() => {...})" öffnen. , aber nichts davon machte einen Unterschied.
Irgendwelche Ideen, was mir hier fehlt? Muss etwas albern sein, aber ich kann es nicht herausfinden. Vielen Dank!
Rate mal, ich muss wirklich auf Async-Programmierung nachlesen. Aus einem Hintergrund der sequentiellen Programmierung herrührend, ist es alles andere als intuitiv für mich, warum eine nachfolgende Aktion ein vorangehendes UI-Update blockieren würde, insbesondere ein Einzelbefehl, obwohl ich verstehe, dass es eine Aufeinanderfolge von aufeinanderfolgenden Aktionen auslöst. Der Task.Run-Ansatz wird mein Problem immer noch nicht vollständig lösen, da das Popup geöffnet wird, aber der Spinner (aus dem gleichen Grund) nicht dreht, aber wie gesagt, ich verstehe die Async-Programmierung nicht. – Lon
Wie ich es verstehe, arbeiten Windows-Apps mit Nachrichtenwarteschlangen. Obwohl Ihre nachfolgende Aktion kommt, nachdem sie der Warteschlange ** hinzugefügt ** wurde, erfolgt die Nachrichtenverarbeitung nicht sofort. Sie setzen also "IsOpen", sperren dann aber den UIhread mit den WLAN-Anrufen, bevor Windows die Chance bekommt, sie zu verarbeiten. Eine andere Alternative ist die Verwendung einer Fortsetzungsaufgabe - siehe [diese Antwort] (http://stackoverflow.com/questions/4331262/task-continuation-on-ui-thread/12335614#12335614). Sie würden Ihren Spinner vor dem 'Task.Run' starten, dann würden Sie ihn in der Fortsetzungsaufgabe als erledigt markieren (z. B. den Spinner deaktivieren). – Tone