0

I have a CDialog derived MFC dialog box that contains a winforms user control by utilizing /clr support and CWinFormsControl:

CWinFormsControl<MyNamespace::MyUserControl> m_userControl;

Everything is working great except for one thing. I have a timer on the control:

private System.Windows.Forms.Timer flashTimer;
this.flashTimer.Enabled = true;
this.flashTimer.Interval = 1000;
this.flashTimer.Tick += new System.EventHandler(this.FlashTimerTick);

There are also a couple of simple properties and another timer that updates a value from a web service. Nothing very complicated at all.

The problem is, after the dialog is dismissed, the timer's Tick event keeps firing, and my control continues to run on and on forever and ever. I would assume that once the HWND was destroyed, the timer would stop and the GC would eventually clean up my object.

I've had a lot of experience with C#/WinForms and C++/MFC, but this is pretty much the first time I've tried to use them together like this. Am I missing something? Do I need to do some sort of manual clean up of the user control?

James R.
  • 822
  • 8
  • 17
  • Did you try explicitly removing the event when the dialog is dismissed? – William Jones Sep 09 '16 at 18:48
  • @WilliamJones, no I haven't done that yet. I suppose that would solve the immediate issue of the timer code continuing to execute, but it seems like a hack. And it also makes me wonder if the control will ever get cleaned up even if I did remove the event handlers. – James R. Sep 09 '16 at 18:53
  • Perhaps the GC is seeing the control as being "used" because of the event hook? – William Jones Sep 09 '16 at 18:54
  • @JamesR.: That's not a hack. It's the event that holds a reference to the control (`this.flashTimer.Tick += new System.EventHandler(this.FlashTimerTick);` creates a circular dependency). You have to explicitly break that reference so that the control can get garbage collected. To debug scenarios like this, consider using WinDbg with the [SOS Debugging Extension](https://msdn.microsoft.com/en-us/library/bb190764.aspx). Issuing the `GCRoot` command *"displays information about references (or roots) to an object"*. – IInspectable Sep 09 '16 at 19:01
  • As an addendum: While .NET's garbage collector can in fact handle circular dependencies, the issue is with the native resources held by the `System.Windows.Forms.Timer`. Breaking the circular dependency is required in this case. – IInspectable Sep 09 '16 at 19:13
  • @IInspectable, thank you so much for the explanation. Is that an issue even in a "normal" C# WinForms app? Or is it due to the fact that I'm throwing it in an MFC window? I ask because it makes me wonder if I've caused this issue in the past and never realized it... – James R. Sep 09 '16 at 19:17
  • This is a common issue, even with pure .NET applications. [Circular References Cause Memory Leak?](http://stackoverflow.com/q/400706/1889329) explains this in a bit of detail (specifically the case of event handlers). If you have been using event handlers in the past (you probably have), chances are that you introduced resource leaks. At least now you know a tool that helps you diagnose these issues. A word of warning, though: [WinDbg](https://msdn.microsoft.com/en-us/library/windows/hardware/ff551063.aspx)'s user interface has somewhat of a steep learning curve. – IInspectable Sep 09 '16 at 19:21
  • Ah yes, good old windbag... Haven't used that in years. – James R. Sep 09 '16 at 19:24

0 Answers0