How to analyze UWP application UI freeze? - user-interface

My UWP app goes into UI freeze state sometimes and I don't know why。 I've checked the code about view model and async-await calls. And I've tried to use the performance profile tool in Visual Studio to get timeline but it only shows the time and duration time about the UI freeze. I have run out of ideas now.
I tried the dotTrace but it seems that I cannot use it to profile UWP application. Even I " disable the Compile with .NET Native tool chain option in Visual Studio (via the menu Project | Properties... | Build) and rebuild the project."
https://learn.microsoft.com/en-gb/visualstudio/profiling/profiling-feature-tour?view=vs-2019

There are many reasons for UI freezing, including code endless loops, asynchronous methods are not handled properly, program errors, etc.
Most of them occur in asynchronous method processing and UI rendering.
When calling asynchronous methods, use the async/await keywords, like:
//define
public async Task asyncMethod()
{ }
//use
await asyncMethod();
Reduce resource consumption when rendering a large number of data templates through virtualization.
If you have a large list to render, if virtualization is not enabled (referring to controls with virtualization, such as ListView), or used, but the conditions of virtualization are destroyed (such as adding ScrollViewer outside ListView ), This will also cause the UI to freeze and will not return to normal until the list is rendered.
Please check your code for the above problems, or provide a minimal reproducible demo so that we can analyze where the problem occurs.
Best regards.

I would suggest you try to use the Visual Studio debugger to find out what the code is doing.
First, make sure that you are set "Debug" mode and that the debugger is going to run on "Local Machine" (there are other options here, but I'm trying to keep things simple).
Then, click on the "Local Machine" button to run your app using the debugger.
Once your app freezes, click on Debug-Break All:
After that, I suggest you use the various Debug commands to further debug your application.
For example, you can use the "Call Stack" menu item/window to view what your code is doing. You can also use the "Threads" menu to see what threads are running. If you have suspect areas in your code, you might consider adding System.Diagnostics.Debug.WriteLine() statements to print out informative messages, and then use the "Output" menu item/window to see what is happening.
If your app first freezes, and then crashes after some time, then this could be because your tasks don't have correct exception handling. You might consider adding an UnobservedTaskException handler to your code to help you find this problem.

Related

How Can Watch Variables be Configured in a Watch Window Before Running a Debug Session in VS2017?

In all of my searching, I have not come across any trick, plug-in, or setting that would allow me to pre-populate a Watch Window for use during debugging.
The well-known steps to watch a variable in Visual Studio 2017 is to set a breakpoint (perhaps on the first instance of a variable being assigned a value), then, adding the variable to a Watch Window. On subsequent runs, that watched variable should remain in the Watch Window.
Is there a way to accomplish pre-populating the Watch Window before a debugging session? I have code that runs in a timed sequence. Taking the extended time during an execution break to pause and set up a watch causes the program to crash. Such timeout crashes while setting up variable watch objects makes for difficult interaction with the debugger. Pre-populating the watch list would help considerably.
I know that I could use a technique such as using Debug.Print(...) statements, which are printed to the Output Window during code execution. However, this doesn't allow me the control and visual feedback to my debugging efforts that comes from a Watch Window.
Watches can only be evaluated when you are paused in the debugger, say on a breakpoint. They can't be evaluated during normal execution. Your options to get around this limiation are:
Add Debug.Print(...) or something similar to your code that outputs a value.
Similar to #1 add a TracePoint which you'll find in the actions setting of a breakpoints setting (that's the gear icon when you hover over a breakpoint). When the TracePoints are hit they will then evaluate the expression that you specficied in the actions window and log it to the Output window. The advantage of TracePoints over adding your own logging is that you can turn it off and on without building your code. More info at: https://learn.microsoft.com/en-us/visualstudio/debugger/using-breakpoints?view=vs-2019#BKMK_Print_to_the_Output_window_with_tracepoints
Use the VS Enterprise only feature Snapshots which is part of IntelliTrace. Basically set your breakpoints but rather than stopping on them to look at the watch just continue. Each time you stop a snapshot of the process will be taken capturing the state of your application at that time. Then once you're finished use the Diagnostic Tools window to select each of the snasphots and activate them. For each snapshot you can use the debugger just as if you stopped the application. So you can use watches and inspect etc. Of course you can't step as the app has already ran but you can go to the next snapshot etc. More info at: https://learn.microsoft.com/en-us/visualstudio/debugger/view-snapshots-with-intellitrace?view=vs-2019 and https://devblogs.microsoft.com/visualstudio/step-back-while-debugging-with-intellitrace/
How Can Watch Variables be Configured in a Watch Window Before Running
a Debug Session in VS2017?
I'm afraid the answer is negative.For now,the Watch window can only be configured after the debug session start.It's like a runtime window only occurs during debugging.
So we can't pre-populate it before debug session for now. In other words, it's by design.
As alternative ways,you can follow Andy's detailed suggestions above.
And since your needs is meaningful in some specific debugging situation, you can also post your suggestion on development community like a user voice to add a new feature.

Standalone IntelliTrace collected recording shows only external code

I am testing the standalone IntelliTrace recorder tool but struggle to use it for post-mortem debugging of a client WPF application.
I managed to record the data using the IntelliTrace recorder. However, when I view the created .itrace file in Visual Studio 2017 15.8.6 Enterprise, I cannot see any references to the code. VS tells me for all events that all threads execute only external or framework code.
The events that have been recorded are mostly WPF button click gestures. Even though the button click method itself is in BCL libraries, I was expecting to see click handler code. Furthermore, I also added a line to throw an exception in my app (which then of course is thrown in the code of the application), but for this, I also cannot see any code.
The collection plan did not make any difference. I was using the builtin ASP.NET Trace collection plan as it is supposed to be verbose, the default plan and a customized plan where I removed everything that is not important for the app under test.
The program database files are located next to the executables as I was executing the program from in its build output directory, so VS should not have any problems finding the pdbs.
The commandline I was using to start the collection is
C:\IntelliTrace\IntelliTraceSC.exe launch /cp:C:\IntelliTrace\collection_plan.ASP.NET.trace.xml /f:C:\IntelliTrace\test.itrace MyApp.exe
Am I missing something? What is required to see the actual code? Currently, I only see the sequence of events, which alone is pretty useless for debugging.
I am using the IntelliTrace collector version 14.0.24720.00.
You have to check your debbuger.
Try Right click on the project and under Configuration Properties -> Debugging there should be a row with Debugger type).
Can you try debugging with the type switched to mixed mode? It seems like you also have managed code running and it may be using the incorrect debugger if it is set to auto.
Are you still getting the same issue?
Also can you try debugging with Just My Code turned off. Tools -> Optio -> Debugging. Make sure Enabled Just My Code is unchecked. Does this issue still appear?
Also, try with:
Debug > Options > General > Uncheck "Enable Just My Code"
All the references that I mention has background in:
https://msdn.microsoft.com/de-de/library/dd264915(v=vs.120)
Hope it fix your issue

Launching MSVC debugger to debug an app from command line without clicking on pop-ups

We want our continuous integration scripts to run our apps on the test environments with MSVC attached to the apps.
I've tried several options like this or this that launch vsjitdebugger.exe but it pops several pop-ups like "Do you really want to start debgging? Yes. Cancel debugging" and "Choose the debugger"( with only one choice in the list). That is unacceptable because ... it is supposed to be automated - to work without humans.
Anyone done that and knows how to truly automate it?
It will have the JIT debugging pop windows during using command line or IDE if we enable JIT debugging to capture the Exception, I often use the following sample as the debugging tool even if it doesn't really meet your requirement:
https://www.codeproject.com/articles/1090417/how-to-set-debugger-to-auto-attach-on-process-star
We could disable JIT without pop window, but it means that it will not really call it:
https://msdn.microsoft.com/en-us/library/5hs4b7a6(v=vs.140).aspx
No other good workaround for it, but I will help you submit a feature request to the product team:
https://visualstudio.uservoice.com/forums/121579-visual-studio-ide/suggestions/17280578-launching-msvc-debugger-to-debug-an-app-from-comma
You could add your comment and vote it:)

In a Visual Studio Extension, how to detect when the debugger Continues

I need my Visual Studio extension to react to debugging events. I've registered a IDebugEventCallback2 and I'm receiving events, but all I get for each event is an opaque IDebugEvent2 and a Guid, many of which are not only undocumented but don't appear anywhere on the web (or in my registry).
My specific requirement at the moment is to know when the process is Continued - ie. the user has hit Continue, Run to cursor, etc. What Guid should I be looking for?
Or is there some other event family that I should be subscribing to?
(More generally, is there some way I'm missing to find out about the events that are delivered to my IDebugEventCallback2::Event callback, when many of them don't appear in MSDN or anywhere else? Thanks!)
There is no easy way to do this. Actions such as Continue and Run to cursor are abstractions implemented by Visual Studio and do not correspond to any unique event(s) with respect to the debug engine. The debug engine event reporting interface IDebugEventCallback2 will enable you to get notified only on fine-grained events such as when creating a breakpoint or reaching a breakpoint.
While Visual Studio enables you to perform actions such as Continue and Run to cursor programmatically, it does not provide a direct way to get notified when they are taken.
You can use EnvDTE.DebuggerEvents.OnXxx events to get notified when something is about to happen. In particular, the OnEnterBreakMode event enables you to intercept a breakpoint hit and possibly take an action. You can also inspect all the details of the reached breakpoint(s) using the current EnvDTE.Debugger inside the event handler.
Now with some effort, you can use these constructs to implement events that correspond to all Visual Studio debugging actions including Continue and Run to cursor accurately. If you require additional events not provided by EnvDTE.DebuggerEvents (such as when a breakpoint is inserted), you have no choice but use IDebugEventCallback2.Event. In this case if you have specific events in mind, please mention them explicitly and I might be able to tell you the corresponding IDebugEventCallback2.Event GUIDs.
You probably got off on the wrong foot here, the IDebugXxx interfaces were really intended to create your own debugging engine. Still useful perhaps to see what is going on in the existing engine, you are suppose to use QueryInterface() to discover the specific interface that matches the event. Like IDebugEngineCreateEvent2, IDebugProcessCreateEvent2, IDebugProcessDestroyEvent2, etcetera. There are a bunch of them, they are listed in the VSSDK\VisualStudioIntegration\Common\Inc\msdbg.h header and include their IID.
Best thing to do is peek at this sample, it shows how to crack the event notification into the specific interfaces. The AD7Events.cs source file shows the wrappers. Do keep in mind that this sample was made to show how to create an engine, not how to use the one already built into VS.
But yes, you are not going to get a "continue debug" event out of this. A debugging engine does not need that event since it is already responsible for taking care of that by itself. It already knows when it calls IDebugProgram3::Continue().
Surely what you are looking for is IVsDebugger.AdviseDebuggerEvents(). That's the one that tells you what the built-in debugger is doing. You need to pass an object of a class that implements IVsDebuggerEvents, your OnModeChanged() method will be called with a DBGMODE notification. I don't see a lot of fantastic examples that demonstrate usage, this web page might be helpful.

Visual Studio Extension: Wait for all projects to complete loading with IVsSolutionEvents OnAfterOpenSolution

I am looking for an event/interface to use that notifies me once all projects have loaded in a solution after opening a solution.
I have implemented OnAfterOpenSolution in IVsSolutionEvents2 interface. This gets called immediately after the solution opens... so any code I run against the UI thread, even asycnhronously, locks up the IDE prior to the project(s) loading.
Is there a similar technique to implementing `OnAfterOpenSolution', that is called once all the projects for the solution have opened?
The OnAfterBackgroundSolutionLoadComplete event in the IVsSolutionLoadEvents interface is fired after all projects for the solution have completed loading. The implementation for this will still need to implement or extend from an implementation of one of the IVsSolutionEvents interfaces in order to attach the event using IVsSolution.AdviseSolutionEvents(..) method.
Upon Further investigation in this area, the OnAfterBackgroundSolutionLoadComplete only occurs if projects are set to load in the background. If the background loading has been disabled this event will not occur. You will likely also have to implement IVsSolutionLoadManager and ensure that at least 1 project has a background load priority if you intend to rely on the OnAfterBackgroundSolutionLoadComplete event, or switch based on how the user has set their loading priority.

Resources