Pergunta

Existem vários tópicos (a, b, c etc.) sobre o fato de que Claro() inserir itens nos contêineres de componentes .NET não Descartar eles(chamando Dispose(verdadeiro).

Na maioria das vezes, IMHO, os componentes Clear-ed não são mais usados ​​no aplicativo, portanto, ele precisa ser explicitamente descartado após limpá-los dos contêineres pai.

Talvez seja uma boa ideia essa coleção Clear método tinha um parâmetro bool dispose que quando verdadeiro também descarta os elementos da coleção antes de removê-los da lista?

Foi útil?

Solução

Pedir modificações como essa é inútil, a equipe do Windows Forms foi dissolvida há algum tempo.Está em modo de manutenção, apenas são considerados problemas de segurança e incompatibilidades de SO.

Caso contrário, é bastante simples criar seu próprio método para fazer isso:

  public static class ExtensionMethods {
    public static void Clear(this Control.ControlCollection controls, bool dispose) {
      for (int ix = controls.Count - 1; ix >= 0; --ix) {
        if (dispose) controls[ix].Dispose();
        else controls.RemoveAt(ix);
      }
    }
  }

Agora você pode escrever:

  panel1.Controls.Clear(true);

Outras dicas

Respondendo à pergunta “qual é o risco”, o risco (ou um risco) é ficar sem puxadores de janela, embora possa demorar um pouco.

Eu tenho um "designer de janelas" que gera uma janela a partir de um script.Cada vez que altero o script, a janela é reconstruída (os controles são limpos e adicionados novamente).Com uma janela particularmente complexa, e usando Controls.Clear() a cada vez, depois de muitas dezenas de atualizações, acabarei recebendo uma exceção "não há mais identificadores de janela" e não poderei criar mais controles.

Fácil o suficiente para substituir o Controls.Clear() ligue com algo como:

Controls.Cast<Control>().ForEach(c => c.Dispose());

A resposta do @Hans Passant é boa, mas no caso de programação assíncrona, você deve considerar remover o objeto antes de descartá-lo para evitar que algum thread itere sobre um objeto descartado.

Mais ou menos algo assim:

public static class ExtensionMethods {
  public static void Clear(this Control.ControlCollection controls, bool dispose) {
    for (int ix = controls.Count - 1; ix >= 0; --ix) {
      var tmpObj = controls[ix];
      controls.RemoveAt(ix);
      if (dispose) tmpObj.Dispose();
    }
  }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top