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.
Related
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'm stumped and need some ideas on how to do this or even whether it can be done at all.
I have a client who would like to build a website tailored to English-speaking travelers in a specific country (Thailand, in this case). The different modes of transportation (bus & train) have good web sites for providing their respective information. And both are very static in terms of the data they present (the schedules rarely change). Here's one of the sites I would need to get info from: train schedules The client wants to provide users the ability to search for a beginning and end location and determine, using the external website's information, how they can best get there, being provided a route with schedule times for the different modes of chosen transport.
Now, in my limited experience, I would think the way to do that would be to retrieve the original schedule info from the external site's server (via API or some other means) and retain the info in a database, which can be queried as needed. Our first thought was to contact the respective authorities to determine how/if this can be done, but this has proven to be problematic due to the language barrier, mainly.
My client suggested what is basically "screen scraping", but that sounds like it would be complicated at best, downloading the web page(s) and filtering through the HTML for relevant/necessary data to put into the database. My worry is that the info on these mainly static sites is so static, that the data isn't even kept in a database to build the page and the web page itself is updated (hard-coded) when something changes.
I could really use some help and suggestions here. Thanks!
Screen scraping is always problematic IMO as you are at the mercy of the person who wrote the page. If the content is static, then I think it would be easier to copy the data manually to your database. If you wanted to keep up to date with changes, you could then snapshot the page when you transcribe the info and run a job to periodically check whether the page has changed from the snapshot. When it does, it sends an email for you to update it.
The above method could also be used in conjunction with some sort of screen scaper which could fall back to a manual process if the page changes too drastically.
Ultimately, it is a case of how much effort (cost) is your client willing to bear for accuracy
I have done this for the following site: http://www.buscatchers.com/ so it's definitely more than doable! A key feature of a web scraping solution for travel sites is that it must send you emails if anything went wrong during the scraping process. On the site, I use a two day window so that I have two days to fix the code if the design changes. Only once or twice have I had to change my code, and it's very easy to do.
As for some examples. There is some simplified source code here: http://www.buscatchers.com/about/guide. The full source code for the project is here: https://github.com/nicodjimenez/bus_catchers. This should give you some ideas on how to get started.
I can tell that the data is dynamic, it's to well structured. It's not hard for someone who is familiar with xpath to scrape this site.
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
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