There is a quite big LOB silverlight application and we wrote a lot of custom controls which are rather heavy in drawing.
All data is loaded by RIA service, processed and bound (using INofityPropertyChanged interface) to the view.
The problem is that first drawing takes a lot time. Following calls to the service (server) and redrawing is quite fast.
I used Equatec profiler to track the problem. I saw that processing takes a couple of miliseconds only so my idea is that the drawing by SL engine is slow.
I'm wondering if it is possible to profile somehow processes inside SL to check which drawing operations are taking too much time. Are there any guidelines how to implement faster drawing of complex custom controls?
Short answer is - No, there's no super easy way of figuring out why your application is slow.
Long Answer:
I have never used Equatec profiler for Silverlight but it seems similar to dotTrace. Either way, they both end up showing the same information as xPerf.
Basically the information you should have in front of you is saying which methods and classes took up the most time to execute.
If that information points back to Silverlight framework graphics engine (agcore.dll and npctrl.dll), you'll have to start a slow process of figuring out what you did wrong.
At this point I strongly recommend that you'll watch every single talk Seema Ramchandani gave about Silverlight performance. Specifically PDC08, Mix09 and Mix10.
Step #1 of perf optimization: Measure. Measure. Measure.
Have a clear baseline of what you're trying to improve, and set a numeric expectation to when performance is good enough.
That way you can verify that your changes are having a positive impact on performance.
Step #2 of perf optimization: Start removing stuff.
In your case, I'd start commenting out controls out off the form. When perf massively improves, you've found your culprit.
Step #3 of perf optimization: Try to fix the weak link.
That's how I would go about solving this issue.
Sincerely,
-- Justin Angel
Try profiling with the Visual Studio profiler in order to get a good measure of your managed code and the native code executing within Silverlight. The profiler will help point you to where you're spending the most of your time (what the hot path's are) and whether or not your spending it in framework (SL) code or your own code.
The basics of profiling are:
Open a Visual Studio Command Prompt (as admin), 'cd' to the directory where your DLL and PDB files are (typically your "Debug" folder)
VSPerfClrEnv /sampleon
VSPerfCmd -start:sample -output:somefile.vsp VSPerfCmd -globalon VSPerfCmd -launch:"c:\Program Files (x86)\Internet Explorer\iexplore.exe" -args:""
VSPerfCmd -shutdown
VSPerfClrEnv /off
You can find detailed instructions on using the profiler on my blog: http://www.nachmore.com/2010/profiling-silverlight-4-with-visual-studio-2010/
If you find that you are spending time within Silverlight, track down the code path to see where your code is triggering the expensive calls, so that you can then investigate specific solutions based on the cause of the slow down.
Hope that helps,
Oren
Related
For my work I used DotTrace to analyze slowness one of our cliƫnts experiences in our WPF desktop application.
I used it before to do this which resulted in the conclusion that the DataBase calls where slow which we could then find a solution for.
This time however, I see 75% of the execution time in Native code and no clear slowness in the user code.
I searched some around and saw a few other people with the same question.
The answer there was either that it's normal (previous snapshot also had just a tiny part of execution time in user code, so that seems okay) or that you can analyze it further if you check the box "Collect native allocations" when making the snapshot (which I unfortunately didn't check).
If I check just the user code most of the execution time resides in DevExpress DLLs which are third party UI components. Could you then say that this is moving towards hardware related slowness (see User code part of the snapshot below)?
I used the Timeline option to create the snapshot.
My questions:
Since the snapshot doesn't show a lot of time in true user code (excluding the DevExpress components), could I then conclude that this slowness isn't caused by inefficiency in our code?
Can I tell anything from the native code part of the snapshot (see screenshot below)?
Is Timeline even handy for this case or are one of the other sampling options clearer?
How would I proceed in such a case to move close to the source of the slowness?
Thanks in advance for your help!
Sebastiaan
Native code part of the snapshot:
The native part is always called by the managed code.
The timeline is not efficient in this case. Here you filtered only the native part.
For this kind of analyzing, i recommand using the Sampling mode where you have a better view of your hot spots. The native part will still be there but you can see which managed code called it.
Stumped here. Posted a similar question before. We have a pretty large WPF app that on some machines runs great, but on others, all of a sudden, one of the CPU cores gets pinned at 100% (just one core) and the app freezes. It usually seems to happen when showing a context menu or a combobox drop-down (i.e. Popup controls) which is why we can't debug this since no user code is executing at that time. It's driving us crazy because again, on most machines it runs fine, but on a few, it freezes.
The odd thing is when we run it in a VM, it runs great there too! Crazy! Not sure what's causing this, or more importantly, where to even begin to look because as I said, no user code is running.
This happens on only about 10% of our machines, but it consistently happens on those machines. All are clean (i.e. relatively fresh OS installs, no crazy apps, etc.) and mostly identical machines spec-wise: similar CPUs, similar RAM, same video drivers and service packs.
So as I stated in the title, can anyone suggest possible reasons why a WPF app would pin the CPU and lock the app on some computers but not others? We're just stumped!
Found it!! Turns out there's a bug in .NET 4.0 regarding UI Automation and the changes MS introduced. Here's the info, and the fix! (Note: Even if you call MS, they will send you a link, but it's always a broken link. I managed to track this down manually.)
Note: Their article talks about a specific case that causes this behavior, but if you google around, you'll see tons of issues around hangs related to those DLLs. The latest is they're promising a fix in the .NET 4.5 runtime (from a MS post on this issue.)
Here's the KB article...
http://support.microsoft.com/kb/2484841/en-us
...and here is the actual hotfix.
http://archive.msdn.microsoft.com/KB2484841/Release/ProjectReleases.aspx?ReleaseId=5583
Crappy video driver? Pull two machines - one where it happens, one where not, and start analyzing differences. Could be hardware defects, bad video drivers, anything in that area. WPF uses the GPU to render if one is there.
Since you seem quite to lack options, i would advice to make a new project with just most basic ComboBox in the Window, doing almost nothing. This should work (check :-) ). Then you add features one by one in the ComboBox and test, for instance when you add command, start with empty one. Do this until it 'breaks'. So you know which feature is the culprit.
You didn t say if all was working with software rendering.
I have a standalone WPF application running on .NET 3.5. Every so often, the display simply freezes up for several seconds. This is most noticeable on screens where something is being updated often. Here is a video showing the problem.
While the display is frozen, the interface remains responsive (video).
I've come across some other posts with similar problems who attributed it to a SW/HW rendering issue. To be safe, I disabled HW rendering altogether, but still have the problem.
I ran a file monitor during the freezes to see if there is some extraordinary file access or activity going on, but nothing is out of the ordinary.
Final note: The target platform is a small touch-screen panel PC without much memory or horsepower (512 MB). I only see this issue on the target, never on my development PC, which has much more in the way of resources.
UPDATE
I thought I had fixed the issue by removing some animation code, but it did not work. I am still encountering the problem and I'm at the end of my rope.
Here's some more things I've tried:
Upgraded to .NET 4.0. Same behavior.
Added debug code to all methods that may be invoked via DispatcherTimer (which are called on the UI thread) to make sure none of them are holding up the UI.
I'm really stumped here and have added a bounty. As I mentioned, the problem only occurs on the target PC (link).
I tend to suspect either .NET GC or the OS swapfile when this kind of behavior shows up.
For the former, you could try the .NET performance counters to monitor for suspect activity.
If the device has a swap file, you can disable it and see if the behavior changes.
As others have said, a profiler (or some what of isolating what condition is inducing the delay - even just attaching and breaking the debugger when it occurs) would be a good way to get more information.
Did you tried to profile the application on the tested system? Using a memory and/or performance profiler?
You could get some good informations out of this type of test : some .Net profilers
And here's one for WPF : WPF profiler from microsoft
The culprit was the following method call:
new HwndSource(new HwndSourceParameters());
This was added to my application because it patched a memory leak problem in .NET 3.5. This work-around can be found here. If I remove this call, the rendering issues go away.
I took out the call and fixed the memory leak in another way (removing storyboard animation and using code behind instead)
I have recently attempted to generate reports in Silverlight 4. In my problem domain, these reports either need to go directly to the printer and/or the client-side SL application creates a PDF and allows the user to store it somewhere.
As for the report, it's roughly composed of 50% flow text (incl. enumerations), 30% tables and 20% charts. The flow text part makes it slighty more challenging, as proper line breaking would have to take place.
So far, I have tried the following approaches - each with its own shortcomings that make them not so much feasible:
Silverlight's own PrintDocument: technically, there are two major concerns. For one, getting page breaks to work and printing UIElements on it with proper layout is a bit of a dirty hackjob and full of compromises; thankfully that's the part I've managed to get working so far. However, the PrintDocument class always renders all visuals as bitmaps before sending them off; this is not so much fun, if one uses a PDF printer and hopes to still be able to search in / select text. David Poll's approach in "Silverlight and Beyond" [1] wasn't that helpful as well as it inherently follows the same approach and thus suffers from very similar issues.
silverPDF [2]: a barely documented library that requires to do most of the layout manually (the former approach at least allowed me to re-use Silverlight's layouting engine). So far, I see no way to (for instance) measure paragraphs and the only sample with long flowtext uses hardcoded absolute values for layout rectangles. Also, the developing party seems to be inactive.
Personally, I'm now thinking of following an entirely different strategy: simply generate HTML documents. But I was hoping that the community here might have hints for the two approaches above or know other good approaches.
Thanks in advance,
~Manny
Do you need to generate the report on the client, or can you get the server to generate it? Your options are better if you can generate it on the server. Personally, I think the way Silverlight printing works at the moment is pretty poor for report usage (sending each page to the printer as raster rather than vector, resulting in potentially huge amounts of data travelling through the network, and lower printing quality output). I've found the best strategy is to generate the PDF on the server (enabling you to take advantage of a reporting engine), and display it in your application. There are also a few commercial products (such as Telerik's Silverlight Report Viewer, Report Sharp Shooter, or even First Floor Software's Document Toolkit). If a client side solution is really required, perhaps one of these might be the best option (although the printing quality will still be poor). Note that Silverlight 5 is supposed to have support for vector printing, but it's another 6 months or more away from release. Yet another option is Pete Brown and David Poll's open source reporting framework here: http://silverlightreporting.codeplex.com/.
If you want to take the option of generating the report on the server as a PDF and displaying it in your application, I've written an article on doing so here: http://www.silverlightshow.net/items/Building-a-Silverlight-Line-Of-Business-Application-Part-6.aspx. This doesn't work for OOB applications, but the source code accompanying my book (Pro Business Applications with Silverlight 4) does: apress.com/book/view/9781430272076.
Hope this helps...
Chris Anderson
During localhost testing of modular Prism-based Silverlight applications, the XAP modules download too fast to get a feel for the final result. This makes it difficult to see where progress, splash-screens, or other visual states, needs to be shown.
What is the best (or most standard) method for intentionally slowing down the loading of XAP modules and other content in a local development set-up?
I've been adding the occasional timer delay (via a code-based storyboard), but I would prefer something I can place under the hood (in say the Unity loader?) to add a substantial delay to all module loads and in debug builds only.
Suggestions welcomed*
*Note: I have investigated the "large file" option and it is unworkable for large projects (and fails to create XAP with really large files with out of memory error). The solution needs to be code based and preferably integrate behind the scenes to slow down module loading in a local-host environment.
****Note: To clarify, we are specifically seeking an answer compatible with the Microsoft PRISM pattern & PRISM/CAL Libraries.**
Do not add any files to your module projects. This adds unnecessary regression testing to your module since you are changing the layout of the module by extending the non-executable portion. Chances are you won't do this regression testing, and, who knows if it will cause a problem. Best to be paranoid.
Instead, come up with a Delay(int milliseconds) procedure that you pass into a callback that materializes the callback you use to retrieve the remote assembly.
In other words, decouple assembly resource acquisition from assembly resource usage. Between these two phases insert arbitrarily random amounts of wait time. I would also recommend logging the actual time it took remote users to get the assembly, and use that for future test points so that your UI Designers & QA Team have valuable information on how long users are waiting. This will allow you to cheaply mock-up the end-user's experience in your QA environment. Just make sure your log includes relevant details like the size of the assembly requested.
I posed a question on StackOverflow a few weeks ago about something related to this, and had to deal with the question you posed, so I am confident this is the right answer, born from experience, not cleverness.
You could simply add huge files (such as videos) to your module projects. It'll take longer to build such projects, but they'll also be bigger and therefore take longer to download locally. When you move to production, simply remove the huge files.