// get the tile data quadrant = GetTileData(); // we are creating UI elements, go via dispatcher map.Dispatcher.BeginInvoke(delegate() { Canvas canvas = new Canvas(); Tile tile = new Tile(quadrant, canvas); // create instance of renderer ITileRenderer tileDrawer = RenderFactory.CreateRenderer(tile); // render the tile tileDrawer.Render(); // tell the requester that the tile available to add to UI tileLoaded(quadrant.Path, tile); });This means multithreading is great if you have complex calculations going in, and just need to update a simple UI. However for code where the complex work is the UI then you end up hitting a bottleneck. In the code for drawing London I am creating 24 tiles which in total contain about 60k poly-line/gons. I am effectively forced to create them in a serial fashion (my code is non-serial, but each tile has to wait for the last tile to stop using the Dispatcher).
On my PC it took about 30seconds to draw the map of London (once you have run it once all the data should be cached). I've made some changes to speed this up, so it now runs in 15 seconds. I updated the Silverlight Map demo to use this version (you may have to delete the XAP file from your cache to get the newer version)
For the production version I will not be trying to draw the whole of London like this, but it does suggest that progressive rendering will be needed to make the application more responsive. (Progressive as in only draw large items on the tile for the first pass, and then add detail in the subsequent background passes)
I'm not sure if this UI blocking issue will be a problem for other developers (most complex UIs are made using bitmap based tile operations so in this case they would only have 24 UI elements vs. my 60k) and for other non UI intensive applications the current threading model is fine. However it would be nice if this large block could be removed - for example only require the Dispatcher when the tile is added to a visible UI element...
No comments:
Post a Comment