Hang an unknown place in a very complex WPF application when the window layout has changed due to the creation of ReportViewr in another thread

I have a WPF application with very complex XAMLs, I need a way to find out that my application freezes when I try to pause execution, the application does not seem to hang, the pointer will be on this line:

System.Windows.Application myApp; . . . . myApp.Run(); // <== this line 

This happens when I change the layout of the taskbar or when Windows Explorer crashes (the taskbar is hidden), if I make these changes in strong repetition, the application will never recover, but when a small change occurs, the application will recover in a few minutes, I need to know the reason of this problem, I doubt the complex XAML files of my application, but I need a way to find out the page or component, or that the source of this freezes.

* EDIT *

I need a tool or a way to find out what XAML is, which consumes controller time!

* EDIT *

I have an exact reason for the freeze, this is due to creating an instance of ReportViewer in another thread. When I deleted the instantiation, it worked fine, it is strange that this error has existed in my application for a long time, but it has been hanging recently, I mean: my application will freeze when you paste one of these codes anywhere in my application:

  new Action(() => { ReportViewer rv = new ReportViewer(); }).BeginInvoke(null, null); 

OR

  new Action(() => { ReportViewer rv = new ReportViewer(); rv.Dispose(); }).BeginInvoke(null, null); 

OR

  new Action(() => { ReportViewer rv = new ReportViewer(); rv.LocalReport.ReleaseSandboxAppDomain(); rv.Dispose(); }).BeginInvoke(null, null); 

My questions:

1. What is the relationship between changing the window layout (resizing the taskbar or moving it) and a report viewer that is not added to any visual tree, why does this cause my application to freeze?

2- How to determine the location of the hang?

3. Several times the application is restored after a few minutes (3-5), but several times freezes in the clock and the application does not recover, why?

4 How can I identify the component or configuration that caused my application to freeze in these circumstances?

By the way, it is very useful for the rest if they are resolved. We spent a lot of time finding this, but we didn’t get the exact reason in combination with the ReportViewer causing the freeze!

+7
source share
4 answers

I will try to answer your questions as fully as possible:

The ReportViewer control is a Windows Forms control and Windows Forms has a problem that can cause the UI thread to block in appropriate cases and, therefore, the application freezes.

When a Windows WM_SETTINGCHANGED message is sent to Windows, the System.Win32.SystemEvents.UserPreferenceChanged event is fired. Some Windows Forms controls, including ReportViewer , listen for this event to refresh themselves when a system parameter changes.

The UserPreferenceChanged event UserPreferenceChanged and unlike other regular events, will call each handler using the SynchronzationContext of the subscribed thread. Therefore, if the ReportViewer was created in a thread other than the main user interface thread (dispatcher thread in WPF), the event activation code will try to make a call and wait for the call to finish, which will never happen on this other thread, thus freezing the user interface.

To determine the location of the hang, you can easily turn off the option "Include only my code in Visual Studio" → "Tools" → "Options" → "Debug", and when the hang occurs, just attach the VS debugger to the hang of the application, it will show you that the application hangs inside UserPreferenceChanged event handling when WaitOne is called.

You can learn more about this in the following articles:

http://www.ikriv.com/dev/dotnet/MysteriousHang.html

Windows Forms hangs after calling show from another thread

+7
source

Simple - do not create ReportViewer in another thread. All elements associated with a single user interface hierarchy MUST come from a user interface stream.

In the create action, run back into the user interface thread to perform the actual creation in the user interface thread.

+2
source

After a pause in the VS debugger, open the Threads window in the Debug / Windows menu. Select them and freeze (from the context menu). Then double-click on each thread to see where it is stuck. Alternatively, right-click on the call stack and show the external code.

0
source

There are a few tricks that I like in such cases:

I have this answer already in How to debug internal error in .NET Runtime?

but this should cover your problem, and also logs each action until the CLR crashes

IntelliTraceEvents and call information is a terrific trick to find everything that happened before the crush happened.

Tools-> Debugging-> General-> Enable .Net Framework Debugging

+

Tools-> IntelliTace-> IntelliTraceEvents and Call Information

+

Tools-> IntelliTace-> Set StorIntelliTace entries in this directory

and select a directory

should allow you to enter the INTO.net code and track every function call. I tried this on a small project example and it works

after each debugging session, it is supposed to create a debugging session record. this is a directory even if the CLR dies if im not mistaken

this should allow you to jump to a verbose call before smoothing the CLR.

Asecond Trick

which can be used in production is an amazing structure called PostSharp :

Check out this tutorial:

http://www.sharpcrafters.com/solutions/logging

after using postsharp as described.

you can for each individual function in your system when it was introduced, when it was grouped, and if an exception was thrown into the log of all variables.

and do all this using a few dozen lines of code.

0
source

All Articles