Debugging a performance issue on ListBoxDragDropTarget (Silverlight Toolkit)? - c#

I have a complex project using SilverLight Toolkit's ListBoxDragDropTarget for drag-drop operations and it is maxing CPU. I tried to reproduce the issue in a small sample project, but then it works fine. The problem persists when I remove our custom styles and all other controls from the page, but the page is hosted in another page's ScrollView.
"EnableRedrawRegions" shows that the screen gets redrawn on every frame. My question is this: How can I track down the cause of this constant redrawing?

I have used XPerf to help track down performance issues related to redrawing in Silverlight. It is not completely straightforward or an easy process, but it can help point you in the right direction to where your problems are.
I started with a great tutorial by Seema about using the XPerf command-line tool to profile CPU usage for a Silverlight app. You can basically load up your app, start sampling with XPerf, perform your CPU intensive operations, and then stop sampling and analyze the profile XPerf generates. When you look at the XPerf charts you can select can filter by some process (such as iexplorer or your browser) to see the total % CPU. You can then select a specific length of time in the profile and drill down to see what functions from which DLLs are taking the most CPU cycles. If you point XPerf to Microsoft's symbol server you should get the specific names of the functions where the app is spending most of its time.
For a Silverlight app it's most important to look at what's going on in agcore.dll, npctrl.dll, and coreclr.dll. If your performance problems are related to redrawing, most of the CPU time is likely spent in agcore.dll since that does most of the graphics related work for Silverlight. You can then drill into that and see the specific functions in agcore.dll that are getting called most often during your sample time.
I understand it is kind of an annoying way to debug since you can only really see what is going on in the core Silverlight functions, but it may be able to help you figure out what is going on. In my case I was able to see that most of the time was spent calculating drop-shadows in agcore.dll. I was then able to figure out I stupidly had some content within a drop-shadow effect that was changing many times a second and causing constant recalculation/redraws of the entire drop-shadow effect.
Once you identify your redrawing issues you might want to look into GPU Acceleration with BitmapCaching if you haven't already. That will help offload some of the redrawing to the GPU and save you some CPU cycles.

Related

(Read)File I/O jitter

I have an application (C# .Net 3.5 and .Net 2.0) that performs multiple readfile operations. However, the system shows hickups (jitter) every now and then. I have attached VTune profiler and performed a locks&waits analysis, see the first image below.
The locks and waits analysis showed that a "Sync Object: Stream filepath" causes the application to be locked (waiting) on all threads. CPU utilization drops to 0% during this period.
Next, I used SysInternals Process Monitor to log what operation was performed when the hickups occurred. It shows a fileread operation that takes approx. 1 second, but only occasionally (jitter). See the second image.
single-click large version of image: here
Single-click large version of image: here
I am puzzled. What could cause this jitter in File I/O? It is a synchroneous read. I have tried to reduce the read buffer from the 32,768b to 4096b, but this did not chance anything. Maybe important to note, the machine used to collect these numbers has an SSD. However, we see similar hickups on machines without SSDs.
Any leads in where to look would be welcome.
This question needs an update. I will post this in the form of an answer as I have solved the issue, yet not in a way that I can say for sure what was the original issue.
I have tried a lot of things to find out what caused the occasional spike in IO read(file) duration. First of all, virusscanners matter, especially McAfee caused some trouble. The comments on the question hinted here already, and #remus rusanu's tip to use WPA/WPR combo showed this as well. WPA/WPR combo pleasantly surprised me and is a valuable tool next to VTune, and ProcMon. The first image shows a spike in McAfee taskmanager just before some long duration flushes and reads start (>1s). The second shows that all information in WPA is nicely linked over all graphs. A nice and strong tool, if searching for that needle in the haystack.
Quicklink large version: here.
Quick larger version: here.
Yet, when I uninstalled the virusscan software spikes did still occur. Less frequently, and they were shorter in duration, but still visible in the application. I have tried numerous things to find out what it was. Used VMWare setups so I could completely strip the system and see if other processes might be the issue. In the end, I gave up. I implemented a system to workaround the issue, and this is sufficient for now. Knowing all the actions I took I would say there was another conflicting process. Another option is the linked unmanaged program, which used Mutexes, maybe doing some problematic stuff. I changed the mutex to CriticalSections, but no direct visible results, so I gave up on that route.
To conclude, unfortunately I have no direct answer. Due to time constraints I was forced to work around it, and will probably never know what the root cause for the issue was. I guess that is real life as well..
Thanks for all the tips, I learned some things I will certainly use in the future.

Form Speed Analyzer for Winforms

I'm trying to help a friend speed up a slow winforms app (Don't usually work with winforms allot). I believe the majority of the issues are Database calls however there is quite a bit going on. For WebDev there are a ton of great apps to analyze Page Load Event, Latency's, and Bottlenecks. Is anyone familiar with and comparable tools for the winforms arena ?
Thanks All !
Any .NET performance profiler will tell you where the time is spent - there is one in certain levels of VS, and several commercial ones (JetBrains, RedGate).
If it is in a database call, you'll be able to work out which one, and look at that.
One problem I've seen in naive WinForms apps can be a lot of stuff being called more than once, particularly when a form opens - it's easy to hook some kind of 'changed' event on a control, which then fires when you're filling in a form, which in turn triggers more changes and then more events. Sometimes you've redrawn everything on the form two or three times before it all settles down. An instrumenting profiler which can track function calls accurately will show you this going on.

What could cause this memory issue?

I'm working on an app for windows phone 8, and I'm having a memory leak problem. But first some background. The app works (unfortunately) using WebBrowsers as pages. The pages are pretty complex with a lot of javascript involved.
The native part of the app, written in c#, is responsible for doing some simple communication with the javascript(e.g. native is a delegate for the javascript to communicate with a server), make animation for page transition, tracking, persistance, etc. All is done in a unique PhoneApplicationPage.
After I had some crashes for out of memory exceptions, I started profiling the app. I can see that the WebBrowsers, which are the big part of the the app, are being disposed correctly.
But the problem I'm seeing is that memory continues to increase. What's worse, I have little feedback from the profiler. From what I understand, the profiler graph says there is a big problem, while the profiler numbers say there's no problem at all...
Note: the step represents a navigation from a WebBrowser to another WebBrowser. The spike is created (I suppose) by the animation between the two controls. In the span I've selected in the image, I was doing a navigation forward and one backward having a maxium of 5 WebBrowsers (2 for menus that are always there, 1 for the index page, 1 for the page I navigate from and 1 for the page I navigate to). At every navigation the profiler shows the correct number of WebBrowsers: 5 after navigating forward, 4 after navigating backward.
Note 2: I have added the red line to make clearer that the memory is going up in that span of time
As you can see from the image
the memory usage is pretty big but the numbers say it's low and in that span of time, retained allocation is lower than when it started...
I hope I've included enough information. I want some ideas on what could cause this problem. My ideas so far are:
-the javascript in the WebBrowser is doing something wrong (e.g. not cleaning some event handler). Even if this is the case, shouldn't the WebBrowser release the memory when it is destroyed?
-using a unique PhoneApplicationPage is something evil that is not supposed to be done, and changing its structure may cause this.
-other?
Another question: why does the graph show the correct amount of memory use while the number doesn't?
If you need more info about the profiler, ask and I will post them tomorrow.
Ok after a lot of investigation I finally was able to find the leak.
the leak is created by the WebBrowser control itself which seems to have some event handler that are not removed when you remove it from a Panel. In fact the leak is reproducible by following these steps:
Create a new WebBrowser
Add it to a Panel or whatever
Navigate to a page, with an image which is big and heavy
Tap somewhere in the blank space of the browser(tapping on the image seems to not create the leak)
remove and collect the browser
repeat from 1
at every iteration the memory of the image is never collected and the memory continue to grow.
A ticket to Microsoft was already sent.
The problem was resolved using a pool of WebBrowsers
I don't think There is enough information to find the cause to your leak, and without posting your entire solution I am not sure there can be, since the question is about locating the root cause of it...
What I Can offer is the approach I have used when I had my own memory leak.
The technique was to:
Open a memory profiler. From your screenshot I see you are using one. I used perfmon. This article has some material about setting perfmon and #fmunkert also explains it rather well.
Locate an area in the code that you suspect that it is likely that the leak is in that area. This part is mostly depending on you having good guesses about the part of the code that is responsible for the issue.
Push the Leak to the extreme: Use labels and "goto" for isolating an area / function and repeat the suspicious code many times (a loop will work to. I find goto more convenient for this matter).
In the loop I have used a breakpoint that halted every 50 hits for examining the delta in the memory usage. Of course you can change the value to feet a noticeable leak change in your application.
If you have located the area that causes the leak, the memory usage should rapidly spike. If the Memory usage does not spike, repeat stages 1-4 with another area of code that you suspect being the root cause. If it does, continue to 6.
In the area you have found to be the cause, use same technique (goto + labels) to zoom in and isolate smaller parts of the area until you find the source of the leak.
Note that the down sides of this method are:
If you are allocating an object in the loop, it's disposal should be also contained in the loop.
If you have more than one source of leak, It makes it harder to spot (yet still possible)
Did you clean up your event handlers? You may inadvertently still have some references if the controls are rooted.

Efficiently creating many instances of a winrt metro control

I want to be able to create a few hundred instances of a winrt control (a search result control) in a C# project. The problem is that doing so takes too long (tenths of a second or worse) and must be done on the UI thread, creating stalls and delays in showing results.
For now I've bypassed the issue by pre-caching many instance of the control during startup. This approach works, but affects the startup time (profiling shows 40% of processor time near startup is spent caching these controls) and creates details to be managed, like the size of the cache.
I think the issue is that every time the control is instantiated redundant work, like re-parsing XAML, is done by the underlying framework. Maybe there's a way to avoid repeating this work? Maybe I can cheaply clone an existing control? Does anyone have ideas?
You could do the pre-caching in a parallel thread. Will make less of an impact on startup time on multicore processors
searchresult.memberwiseclone wil give you shallow copies. It might be faster, not sure
Could you use just one searchresult and fill it with the right data just before use? In that case there is no need to create a lot. Just use one as a re-usable container.
If the time is spent when adding the controls to the parent forms you could use
suspendlayout/resumelayout (this is win32)
setting parent to invisible and back to visible when you are done
Is there another way to do the same things faster? (competing control, 3d party etc)
Forenote: it's been awhile so Microsoft may have fixed the win8 app UI virtualization by now. I haven't checked.
What I ended up doing at the time was just hacking together my own UI virtualization to work around the issue. Basically: caching controls and re-using them to display the viewable data (using a binary search tree to efficiently query what can be seen). I wrote a blog post about it.

Update .NET desktop application in real-time

I have no experience building a .NET desktop application, all my experience is with the web. A friend of mine has asked me to do a quick estimate for a small desktop application.
The application just displays a list of items from the database. When rows are deleted/added from the database, they need to be deleted/added from the list on the user's desktop.
Is this done pretty easily in a desktop application, or do I need to do any sort of "reload" every X seconds?
The simplest design would involve polling the database every so often to look for new records. Adjust the number of seconds between polling to best reflect the appearance of real time and also for performance.
Any design that would allow the database management system to broadcast updates to a desktop application would be quite complicated and (depending on your needs) would most likely be overkill.
Elaborating on Andrew Hare's design slightly, I'd suggest that you include some sort of mechanism to 'short-circuit' the refresh cycle when user interaction occurs, i.e.
Refresh every x seconds
AND
Immediatey if the user clicks a control that is deemed to be a critical one AND the required update is less than x records
EXCEPT
where this would increase the refresh rate beyond a certain throttle value
Basically, you want to give the impression of high performance. Perceived performance doesn't mean accomplishing tasks quickly, it's more like doing the slow work during periods that you expect the user to be thinking, faffing around or typing something, rather than when they're waiting for a response. Very few applications are busy even a small fraction of the time they are running - any perceived slow performance is derived from a poor design where the program does too much work at once at the point the user asks for it, requiring them to wait. Caching in the background allows you to only assign the bare minimum amount of work to directly respond to user input, improving the user's perception of performance.
Trying to be directly helpful:
You state you're using .Net - which is handy. .Net databinding is very rich and powerful, and is quite likely to make this job a breeze.
However - read on...
There is a chance that it won't do exactly what you want. This is where databinding becomes a massive pain. Databinding requires certain things to be set up the way .Net wants it, and if they aren't, it's quite a lot of work reimplementing the basic functionality in the way you require. In this case, don't hesitate to reach for the MSDN documentation, and StackOverflow. Ask Early, Ask Often.

Categories