none
Memory Leak in ReportViewer control in VS2008 RRS feed

  • Question

  • We're using the ReportViewer control in two ways: one is to display the report on UI within a Windows Form; the other is to generate the PDF and Excel report files in the background without displaying in a Windows Form. From our tests, the UI version would not have memory leaks. However, the one running in the background is leaking memory pretty quickly. We implemeted the Dispose() method and inside it we did the following:

    private void NullRefOnUserPreferenceChanged(object o, string field)
        {
            FieldInfo fi = o.GetType().GetField(field, BindingFlags.NonPublic | BindingFlags.Instance);
            if (fi != null)
            {
                int i;
                ToolStripTextBox tb = (ToolStripTextBox)fi.GetValue(o);
                object tbc = tb.Control;
                if (tbc != null)
                {
                    Delegate d = Delegate.CreateDelegate(typeof(UserPreferenceChangedEventHandler), RuntimeHelpers.GetObjectValue(tbc), EVENTHANDLER_ON_USER_PREFERENCE_CHANGED);
                    object handlers = typeof(SystemEvents).GetField(LIST_HANDLERS, BindingFlags.NonPublic | BindingFlags.Static).GetValue(null);
                    object upcHandler = typeof(SystemEvents).GetField(ON_USER_PREFERENCE_CHANGED_EVENT, BindingFlags.NonPublic | BindingFlags.Static).GetValue(null);
                    object systemEventInvokeInfo = typeof(SystemEvents).GetNestedType(SYSTEM_EVENT_INVOKE_INFO, BindingFlags.NonPublic | BindingFlags.Instance);
                    object upcHandlerList = NewLateBinding.LateIndexGet(handlers, new object[] { upcHandler }, null);
                    int targetCount = 0;
                    for (i = 0; Operators.ConditionalCompareObjectLess(i, NewLateBinding.LateGet(upcHandlerList, null, "Count", new object[0], null, null, null), false); i++)
                    {
                        systemEventInvokeInfo = NewLateBinding.LateIndexGet(upcHandlerList, new object[] { i }, null);
                        Delegate target = (Delegate)systemEventInvokeInfo.GetType().GetField(TARGET_DELEGATE, BindingFlags.NonPublic | BindingFlags.Instance).GetValue(systemEventInvokeInfo);
                        if (target.Target == d.Target)
                        {
                            targetCount++;
                        }
                    }
                    for (i = 1; i <= targetCount; i++)
                    {
                        SystemEvents.UserPreferenceChanged -= ((UserPreferenceChangedEventHandler)d);
                    }
                }
            }
        }

    But it seems it's not working well. Can anybody help on this?

    Thanks in advance!

    Baolin

    Tuesday, January 29, 2013 3:40 AM