C#: Form containing OpenFileDialog. Both call ShowDialog(). Memory Leak? - winforms

I have a form containing an OpenFileDialog added through the Visual Studio designer. I show the form using the following pattern:
using (var form = MyForm()) {
form.ShowDialog();
}
Then in the form I call
myOpenFileDialog.ShowModal();
Because the OpenFileDialog was added through the designer I can't use the using pattern above. Furthermore, in the Designer.cs file it doesn't appear that
myOpenFileDialog.Dispose();
is called. Do I have a memory leak here?

There is no leak, but the OpenFileDialog will be disposed when the GC runs or the application went down. You can verify this by adding one function break point in visual studio for System.ComponentModel.Component.Dispose since the OpenFileDialog is derived from Component.
So I think it's better to dispose it by yourself when you no longer need it.

Related

WPF Popup permanently displays in Visual Studio design-time

I’ve met strange behaviour for WPF design-time in Visual Studio 2010: after an instance of the Popup class was created, and I switched the code tab in Visual Studio to a different file, the Popup still remains on the screen!
I have a piece of code, which allows to reproduce this, but I am not sure if I should paste it here (it's not so short), so maybe I'll just give a link to it: here.
For unknown reasons beyond mere mortals' comprehension, Microsoft has decided this is the default behavior of the Popup class in WPF. You have to implement the "hiding" logic yourself. I suggest handling the Window.LocationChanged, Window.Activated and Window.Deactivated events of the Window containing the Popup and close it yourself.
Edit: To clarify myself, the Window events you need to handle are the events of the window that contains the Popup's PlacementTarget element. Usually when you create a popup, you set it relative to some element contained in an application's Window (similar to how the tooltips work). If this is your case, then my solution is correct, but I forgot to mention this point about the PlacementTarget.
In your code behind; you can simple check this boolean:
DesignerProperties.GetIsInDesignMode(this);
"this" represent the object containing the popup. For example the Window.
If true you can say:
myPopUp.IsOpen = false;
For Store Apps/WinRT:
Windows.ApplicationModel.DesignMode.DesignModeEnabled

How can I force garbage collection of a window?

I am trying to pro-actively ensure I am not causing memory leaks in my code by keeping an extra weak reference to an object, and checking it is no longer active when it should be released (this is conditional code so it only runs when I am testing).
To simply reproduce the effect I am seeing, create a new WPF Application and put a Button on the main window. Create another window, and put a TextBox on it. In the click handler for the button, put the following code:
Window1 w = new Window1();
WeakReference weak = new WeakReference(w);
w.ShowDialog();
w = null;
// Equivalent to Application.DoEvents() just in case...
Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new Action(delegate { }));
GC.Collect();
GC.WaitForPendingFinalizers();
if (weak.Target != null)
MessageBox.Show("Memory Leak");
When you run this, click on the button and when the window displays, just click on the 'x' to close it and nothing happens - all good. Now do the same thing, but when the window displays, click into the TextBox and then click on 'x'. I get the "Memory Leak" message every time.
Ants Profiler shows System.Windows.Documents.TextEditor has a reference to the TextBox (which presumably gets set up only if you focus the TextBox), and the TextBox has a reference to the window. Its not a real memory leak because if you do the process multiple times, previous windows get collected, just not the latest. However, it means I cannot write tests that confirm memory is not leaking.
Am I the only person wanting this level of assurance, or is there another way?
I think some people have missed the point of your question. You're not trying to force GC's hand, but rather preemptively discover any memory leaks, and for that I applaud you.
In this particular case, it appears as though TextEditor (which is internal) is adding event handlers and has not yet had a chance to detach when your check runs. Have you tried explicitly shifting focus out of the closed window before pumping the dispatcher?
I think you will continue to run into these kind of issues if you attempt to do these tests in your application proper, rather than in the more controlled environment of integration tests, so perhaps you need to re-think your approach.
If previous instances get collected, it's not a memory leak. The garbage collector doesn't always take the most recent items, and it's by design. If you try to second-guess it you'll likely run into problems.
In a real memory leak items will accumulate without ever being reclaimed. That's something best detected using the profiler.
Windows are not just managed by your code but also by some WPF classes like Application. Calling Collect does not guarantee or prove anything, the window does get collected eventually.
try with DispatcherPriority.ContextIdle
Dispatcher.CurrentDispatcher.Invoke( DispatcherPriority.ContextIdle, new System.Action(delegate { }));

Handling events for an Inherited Form

I have a base Windows Form with a control. I have declared the control to be protected so his siblings will be able to handle properties, methods and events. This form is written in c#.
One of my clients is using VB.NET, and they have created a new inherited form in their project. Everything works fine ...
But, When they want to handle the control's clicked event in vb.net they're getting this error message:
"Handles clause requires a WithEvents variable defined in the containing type or one of its base types".
Can anybody tell me what should i do on the c# form to let the inherited form in vb.net use the control events?
Thanks for your help!
Two options:
Write some VB which declares a protected WithEvents variable, then decompile it to see what the VB compiler does. (I believe that it makes it a property for one thing, and probably adds a bunch of other bits and pieces.)
Tell them not to use a Handles clause - get them to subscribe explicitly in the same way that you would from C#, using AddHandler and AddressOf.

Custom Control and Visual Studio 2008 SP1

I've created a custom control (a class that inherits from Control). When I put it on a Form I can work with it on Visual Studio IDE. It shows me an error and I don't see the form.
The error message is this: La variable 'ctrlImagen' no está declarada o no se asignó nunca.
It's a winform for a Compact Framework app.
How can I solve this? (it the class inherits from UserControl it works perfectly)
Sounds crazy, but Visual Studio is selectively executing code for your control in the designer. First thing to check is your constructors. Make sure you have an empty, default constructor, that is public, even if you never plan on using it. After that make sure any code you have tied to layout events (such as resize) are good to go, these are likely the culprits, as thats where I always find problems when my custom controls don't work in the designer.
It sounds like you have a bug in the code for your Control. This sounds like a runtime error that is preventing the control from rendering.
Re-read your code and look for potential null-pointer exceptions, unassigned variables, stack overflows, etc. The bug is lying in their somewhere.
Any chance your user control doesn't have a public default constructor? I can get a similar error "The variable 'userControlX' is either undeclared or was never assigned' if the constructor isn't public.
Would need more info, though.
It seems a design time exception has happened in initialization logic that gets executed before your form initialization logic executed. A good example would be a NullPointerException fired by the default constructor (or one or more methods it invokes) of a user control that contained by your form.
I put this on constructor to solve the problem:
this.ClientSize = new Size(21, 21);
The beging of my class is this:
public class ControlMapa : Control
{
public ControlMapa()
{
this.ClientSize = new Size(21, 21);
...
Thank you!

WPF Memory Leak on XP (CMilChannel, HWND)

My WPF application leaks memory at about 4kb/s. The memory usage in Task Manager climbs constantly until the application crashes with an "Out of Memory" exception.
By doing my own research I have found that the problem is discussed here: Track down memory leak in WPF and #8 here: http://blogs.msdn.com/jgoldb/archive/2008/02/04/finding-memory-leaks-in-wpf-based-applications.aspx
The problem described is:
This is a leak in WPF present in versions of the framework up to and including .NET 3.5 SP1. This occurs because of the way WPF selects which HWND to use to send messages from the render thread to the UI thread. This sample destroys the first HWND created and starts an animation in a new Window. This causes messages sent from the render thread to pile up without being processed, effectively leaking memory.
The solution offered is:
The workaround is to create a new HwndSource first thing in your App class constructor. This MUST be created before any other HWND is created by WPF. Simply by creating this HwndSource, WPF will use this to send messages from the render thread to the UI thread. This assures all messages will be processed, and that none will leak.
But I don't understand the solution!
I have a subclass of Application that I am using and I have tried creating a window in that constructor but that has not solved the problem.
Following the instructions given literally, it looks like I just need to add this to my Application constructor:
new HwndSource(new HwndSourceParameters("MyApplication"));
The fix:
Application.xaml.cs
class MyApp1 : Application
{
// ...
public Application()
{
new HwndSource(new HwndSourceParameters());
}
// ...
}

Resources