Я хочу свою память назад! Как я могу действительно расположить управление?

У меня есть заявка, которую я подаю, который создает большое количество средств управления окнами (кнопки и маркировки и т.д.). Они все делаются динамично через функции. Проблема, которую я имею, когда я удаляю средства управления и располагаю их, они не удалены из памяти.

void loadALoadOfStuff()
{
    while(tabControlToClear.Controls.Count > 0)
        tabControlToClear.Controls[0].Dispose();
    //I even put in:
    GC.Collect();
    GC.WaitForPendingFinalizers();
    foreach(String pagename in globalList)
        tabControlToClear.Controls.Add(MakeATab(pagename));
}

TabPage MakeATab(string tabText)
{
    TabPage newT = new MakeATab();
    newT.Text = tabText;
    //Fill page with controls with methods like this
    return newT;
}

Теперь по некоторым причинам это просто не дает мне мою память назад, поэтому когда процесс работает 5 раз, я заканчиваю с из нарушения памяти. Я плохо знаком с объектом и распоряжением управления, но просмотр обширной сети все еще не дал мне признаков, поэтому если бы у какого-либо из Вас есть идея, я был бы благодарен услышать его.

ОБНОВЛЕНИЕ: я следил за созданием пользовательских объектов и разрушением (taskmanager) и заметил, что создаю вкладку, добавляю обработчик щелчков, добавляю панель, добавляю 2 кнопки и с обработчиками щелчков, подсказками и с backimages (я думаю, что это - то, где проблема). В приложении говорится, что оно создает 8 новых объектов, но когда я пробегаю мой располагать, я только удаляю 4 из памяти. Я пытался удалить обработчики событий, но это, кажется, не имеет никакого значения.

РАЗРЕШЕННЫЙ!!! Поскольку я добавлял новые объекты к панели, я передавал их подсказка (глупый, но я учусь). Для кого-либо еще, у кого есть та же проблема, (благодаря комментариям и направлениям от людей ниже. Я обнаружил, чтобы заставить управление действительно расположить (поскольку я понимаю, что так неправильно выразился):

1: ЕСЛИ У ВАС ЕСТЬ ПОДСКАЗКА, УДОСТОВЕРЬТЕСЬ ACCESSABLE IT! НЕ ДЕЛАЙТЕ ЧТО Я DID! Например:

Это НЕПРАВИЛЬНО!

TabPage MakeATab(string tabText)
{
    TabPage newT = new MakeATab();
    ToolTip myTip = new ToolTip();
    newT.Text = tabText;
    //Fill page with controls with methods like this
    myTip.SetToolTip(newT, "Something to say");
    return newT;
}

Если Вы сделаете это, то Вы потеряете указатель на подсказку, и поскольку подсказка не является ребенком объекта, это подключено с (скорее подсказка делает сильную ссылку на управление), то даже при уничтожении управления подсказка, к которой Вы не можете получить доступ, поддерживает объект.

2: Перед чем-либо назовите подсказку. RemoveAll (). Это удаляет все, что это - связи со средствами управления. Отметьте при использовании этой подсказки для других средств управления они просто потеряли свою подсказку.

3: Удалите любой внутренний контроль из основного управления. ControlCollection (если они используют не управляемую память, я предполагаю. Я делаю его причина, это заставляет мое приложение работать так...),

4: удалите любые пользовательские обработчики событий.

5: наконец, расположите объект. Я сделал быструю функцию рекурсивного вызова, которая делает это вполне хорошо.

    private void RecursiveDispose(Control toDispose)
    {
        while (toDispose.Controls.Count > 0)
            RecursiveDispose(toDispose.Controls[0]);

        if (toDispose.BackgroundImage != null)
            BackgroundImage = null;

        if (toDispose.GetType() == typeof(Button))
            toDispose.Click -= [Your Event];
        else if (toDispose.GetType() == typeof(TabPage))
            toDispose.DoubleClick -= [Your Event];
        else if (toDispose.GetType() == typeof(Label))
            toDispose.MouseMove -= [Your Event];

        toDispose.Dispose();
    }

Это чрезвычайно сыро и существует, вероятно, намного лучший способ сделать его, но если кто-то не может придумать его, это должно будет сделать. Спасибо за Вашу справку все. Вы, возможно, просто сохранили мой весь проект.

7
задан 12 January 2010 в 11:44
поделиться

4 ответа

Ваш код требует, чтобы класс Dog переопределял метод toString () , чтобы он знал, как распечатать сам себя. В противном случае код выглядит правильно.

-121--2797438-

Что я делаю, так это то, что мой контроллер просмотра настраивает вид прокрутки:

[scrollView setCanCancelContentTouches:NO];
[scrollView setDelaysContentTouches:NO];

И в моем дочернем представлении у меня есть таймер, потому что двухпальцевые касания обычно начинаются как один палец, за которым быстро следуют два пальца.:

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    // Hand tool or two or more touches means a pan or zoom gesture.
    if ((selectedTool == kHandToolIndex) || (event.allTouches.count > 1)) {
        [[self parentScrollView] setCanCancelContentTouches:YES];
        [firstTouchTimer invalidate];
        firstTouchTimer = nil;
        return;
    }

    // Use a timer to delay first touch because two-finger touches usually start with one touch followed by a second touch.
    [[self parentScrollView] setCanCancelContentTouches:NO];
    anchorPoint = [[touches anyObject] locationInView:self];
    firstTouchTimer = [NSTimer scheduledTimerWithTimeInterval:kFirstTouchTimeInterval target:self selector:@selector(firstTouchTimerFired:) userInfo:nil repeats:NO];
    firstTouchTimeStamp = event.timestamp;
}

Если второй касание начинается: событие приходит с более чем одним пальцем, ракурсу прокрутки разрешается отменять касания. Таким образом, если пользователь выполняет панорамирование с использованием двух пальцев, в этом представлении появится сообщение touchesCanced: .

-121--1151870-

Необходимо также очистить ссылку.

while(tabControlToClear.Controls.Count > 0)
{ 
    var tabPage = tabControlToClear.Controls[0];
    tabControlToClear.Controls.RemoveAt(0);
    tabPage.Dispose(); 

    // Clear out events.

    foreach (EventHandler subscriber in tabPage.Click.GetInvocationList())
    {
        tabPage.Click -= subscriber;
    }
}
6
ответ дан 7 December 2019 в 01:21
поделиться

В этом блоке кода вы вызываете утилизацию, но не удалив ссылку:

while(tabControlToClear.Controls.Count > 0)
    tabControlToClear.Controls[0].Dispose();

Вам необходимо удалить все ссылки на элемент управления (в коллекции элементов управления плюс любые зарегистрированные обработчики событий Кроме того, любые другие ссылки, которые вы могли бы иметь) для контроля, который должен иметь право на сбор мусора.

4
ответ дан 7 December 2019 в 01:21
поделиться
void loadALoadOfStuff()
{
    while(tabControlToClear.Controls.Count > 0)
        tabControlToClear.Controls[0].Dispose();
    //I even put in:
    GC.Collect();
    GC.WaitForPendingFinalizers();
    foreach(String pagename in globalList)
        tabControlToClear.Controls.Add(MakeATab(pagename));
}

Мне кажется, вы повторно выделяете все экземпляры вкладок в конце вашего теста-метода, поэтому там явно не пользуется их удалением. Пропустите последние две линии и посмотрите, если это поможет.

0
ответ дан 7 December 2019 в 01:21
поделиться

До сих пор на вопрос было дано много отличных ответов, в которых упоминается одна возможная причина, по которой объекты не освобождаются, это все вещи, которые стоит проверить.

Однако, когда я получаю подобную проблему, я использую профилировщик памяти , чтобы помочь отследить ссылку(и) на объекты, в последний раз, когда я смотрю на профилировщики памяти, профилировщик памяти ANTS (из RedGate) был одним из лучших. (Они делают 14-дневный хвост, который более чем достаточен, чтобы исследовать одну такую проблему)

Это одна из причин, по которой используется паттерн Слабых Событий, однако это был бы совершенно новый вопрос .

(Время жизни объектов пользовательского интерфейса, когда вы динамически модифицируете пользовательский интерфейс, является минным полем, что хорошо сделано для того, чтобы менеджер задач проверил, что ваш код работает так, как ожидается)

.
0
ответ дан 7 December 2019 в 01:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: