WPF laden van grote databound files legt UI totaal stil.

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • hobbit_be
  • Registratie: November 2002
  • Laatst online: 04-07 12:07
Op werk gebruiken we WPF al een tijdje. Met name een tool gebruiken we enorm vaak: he is in feite niets meer dan een enorm grote 2D 'paper' waarop mensen text, images etc kunnen plaatsen en af en toe links leggen. (het doet wel wat meer maar dat is NDA).

we hebben dus een Classe structuur met die data:

code:
1
2
3
4
5
6
7
8
9
10
class Image();
class Question();
class Note();

class Data()
{
    Image[];  //array of
    Question[]; //array of
    Note[]; //array of
}


er zijn gemiddeld 30 stukjes text, 10 images, en een tiental notes per 'pagina'.

Het laden van de xml naar de dataclass (zonder databinding) is geklaard in een 100ms.

Maar zodra we de databinding met de visuele templates terug 'aanzetten' gaat het enorm traag (lees 5 , 10 seconden). + de UI ligt totaal plat. De visuele templates zijn echt niet zwaar: een paar lijntjes, text, en image objects. De images kunnen we groot zijn, maar ook als der geen zijn gaat het traag (dus geen loading of images probleem).

We willen dus graag dat de user ziet dat er iets gebeurt met het loaden van deze file. Helaas licht de UI thread volledig lam: i.e. Het lijkt alsof de Databound methode het ons onmogelijk maakt om iets te laden met een progressbar. Zelfs met sleeps! en backrgound workers tussen het bouwen van de Data class maakt niets uit. Je ziet niets totdat alles der is en totaal geen feedback.

En natuurlijk kun je in WPF geen render forceren (behalve gore hacks die echt niet altijd werken) dus we staan een beetje 'mat'.

Het enige wat we willen is dat de user een 'loading... 25%' te zien krijgt terwijl we data class opvullen (en de binding die dan de controls, image loading, voor ons doet). het lijkt me dat zoiets tamelijk vaak moet voorkomen (i.e. een photoviewer app enzo). Maar de databound class moet in UI thread wonen dus tja... what to do?

Iemand meer ervaring met hoe we het databound methode kunnen gebruiken voor het laden van een grote file + weergeven van status op de UI? (dat het lang duurt maakt ons niet uit: dat we de user echt niets feedback kunnen geven is disgracefull)

WPF is de toekomst van windows programming maar ze maken bepaalde zaken zo onduidelijke en inconsistent.

Acties:
  • 0 Henk 'm!

  • TeeDee
  • Registratie: Februari 2001
  • Laatst online: 20-09 23:58

TeeDee

CQB 241

Voordat je de data gaat binden kan je toch een 'waitscreen'/modal popup tonen en als de data ingeladen is, deze weer netjes weghalen?

Betreft het hier trouwens een 3rd party grid of de native versie van WPF? Ik weet namelijk dat het Grid van DevEpxress nogal traag overkomt.Het Silverlight grid is nog traag. Het DXGrid weet ik niet zeker.

[ Voor 11% gewijzigd door TeeDee op 22-05-2009 14:30 ]

Heart..pumps blood.Has nothing to do with emotion! Bored


Acties:
  • 0 Henk 'm!

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

De ObjectDataProvider kan het voor je doen: http://nayyeri.net/blog/a...-presentation-foundation/

Of je doet het zelf: http://blogs.msdn.com/kar...ve/2006/01/27/518499.aspx

En vergeet ook niet te kijken naar UI virtualization: http://www.kirupa.com/net/ui_virtualization_pg1.htm

We adore chaos because we like to restore order - M.C. Escher


Acties:
  • 0 Henk 'm!

  • Brainstorm
  • Registratie: November 2000
  • Laatst online: 20-09 13:56
[edit] Hmm ObjectDataProvider ziet er wel handig uit :) Die kende ik nog niet. Ik dacht dat er ook een whitepaper van MS ergens is over UI en threading in WPF, ik kan hem alleen zo snel niet vinden.


Afaik kan dit niet. De UI is ook in WPF nu eenmaal singlethreaded en als die voor langere tijd bezig is kunnen de redraw events niet afgehandeld worden. Ik denk dat je toch in de richting moeten kijken van het stap voor stap binden van de controls. In dat geval dus geen automatische databinding, maar iets meer code zelf schrijven.

Ik denk niet dat een model dialog 100% werkt, zodra je namelijk een window over je applicatie heen plaatst en weer weghaalt moet windows toch de interface opnieuw tekenen.

Toevallig ben ik momenteel met een soortgelijk iets bezig. Omdat daar het laden van de data relatief lang duurt (komt via een webservice binnen) loopt er op de achtergrond een thread die de gegevens ophaalt. Vervolgens wordt er via de Dispatcher en Invoke voor gezorgd dat de interface bijgewerkt wordt (simpele progressbar, in mijn geval). Dit dus eigenlijk hetzelfde als in WinForms, alleen is in WPF er een Dispatcher voor: http://msdn.microsoft.com/en-us/magazine/cc163328.aspx

[ Voor 9% gewijzigd door Brainstorm op 22-05-2009 14:40 ]

Programmer's Drinking Song: 99 little bugs in the code, 99 bugs in the code, Fix one bug, compile it again, 100 little bugs in the code. (go to start if bugs>0)


Acties:
  • 0 Henk 'm!

  • hobbit_be
  • Registratie: November 2002
  • Laatst online: 04-07 12:07
Teedee: alle objecten zitten in een canvas maar sommige objecten hebben zelf nog een grid ook. We doen idd al een popup en dan wachten...... :) en dan nog eens wachten totdat het 'verschijnt'

LordLarry: dat zijn een hoop goede links! vooral de tweede. UI virtualisation is niet toepasbaar hier (i.e. the view by loading is meestal fullscreen, ook is het qausi onmogelijk te achterhalen waar dingen nu eigenlijk staan op het scherm (nog een kwalijk puntje van WPF).

- Maar die tweede tip lijkt me een goed plan voor te implementeren volgende week, die ObjectDataProvider zie ik niet direct de oplossing omdat de eigenlijk data echt maar 1 xml files is die wordt geparsed. Dan blijft het probleem dat ie alles ineens wil tonen.

- eigenlijk gek dat een callback 'onRendered' niet bestaat - dit zou de databinding nog handiger maken.

Bedankt voor de tips - ik zal het resultaat hier posten

Overigens was mijn idee om de data via onze socketbased message door te sturen (tis een networked app) en misschine 'beslist' de Render thread dan om iets vaker te refreshen :)