2016-05-08 4 views
0

Ich benutze ein Canvas als Host für Tausende von DrawingVisuals. Das Laden ist sehr langsam. Ich habe nur versucht, die bei sichtbaren DrawingVisuals beginnen zu laden und mit async und wartet auf die anderen DrawingVisuals:Wie wird DrawingVisuals asynchron mit Async und Await geladen?

Async Sub AddVisuals() 
    Dim visuals = Await Task.Run(AddressOf CreateVisuals) 
    For Each vis In visuals 
     AddVisualChild(vis) 
     AddLogicalChild(vis) 
    Next 
End Sub 
Function CreateVisuals() As DrawingVisual() 
    .... 
End Function 

Aber Task.Run ruft einen anderen Thread. So bekomme ich eine InvalidOperation-Ausnahme, die besagt, dass das Objekt einem anderen Thread gehört. Aber here Ich finde:

Die async und warten Schlüsselwörter zusätzliche Threads verursachen keine geschaffen werden. Async-Methoden erfordern kein Multithreading, da eine asynchrone Methode nicht in einem eigenen Thread ausgeführt wird. Die Methode wird im aktuellen Synchronisationskontext ausgeführt und verwendet die Zeit im Thread nur dann, wenn die Methode aktiv ist. Sie können Task.Run verwenden, um CPU-gebundene Arbeit in einen Hintergrundthread zu verschieben, aber ein Hintergrundthread hilft nicht bei einem Prozess, der nur darauf wartet, dass Ergebnisse verfügbar werden.

Also gibt es eine Möglichkeit, ein DispatcherObject (hier: DrawingVisual) mit async hinzuzufügen und zu erwarten?

+0

Da ich Visual Studio 2010 benutze, habe ich nicht mit async/await gearbeitet, aber würde 'Dim visuals = CreateVisuals()' nicht den Trick machen? Oder einfach 'Dim visicals = CreateVisuals()', da CreateVisuals() den aktuellen Thread blockieren sollte, bis er zurückkehrt. –

+0

Aber ich möchte den aktuellen Thread nicht blockieren. Das Zeichnen aller Visuals dauert zu lange und blockiert die Benutzeroberfläche. – ubsch

+0

Warum verwenden Sie dann 'Await'? –

Antwort

0

Um Ihr Ziel zu erreichen "Ich möchte die derzeit nicht sichtbaren DrawingVisuals - später können sie durch Scrollen sichtbar werden - im Hintergrund geladen werden, ohne die Benutzeroberfläche zu blockieren", schlage ich vor, Sie versuchen UI Virtualisierung statt Async ... Erwarten.

Legen Sie die IsItemsHost-Eigenschaft des Containersteuerelements auf True fest, und Sie können dann die ItemsPanel-Eigenschaft auf VirtualizingStackPanel festlegen und IsVirtualizing auf true festlegen.

Lesen Sie mehr auf https://msdn.microsoft.com/en-us/library/cc716879(v=vs.100).aspx

+0

Ich habe das versucht, aber die Zeichnung in visula.RenderOpen ist so langsam, dass es kein reibungsloses Scrollen gibt. Aber ich habe eine Lösung gefunden. Schau dir meine Antwort unten an. – ubsch

1

fand ich eine Lösung: visual.Dispatcher.InvokeAsync(Sub() DrawVisual) Awaitable ist. Und so habe ich es mit Await benutzt. (In DrawVisual RenderOpen wird aufgerufen) Jetzt werden alle DrawingVisuals schneller geladen und die UI ist nicht mehr geblockt. Danke Visual Vincent und Scott für deine Posts.

Verwandte Themen