Clear controls does not dispose them - what is the risk?

前端 未结 3 1415
遇见更好的自我
遇见更好的自我 2020-11-29 11:15

There are multiple threads(a, b, c etc.) about the fact that Clear() ing items in the .NET component containers does not Dispose them(by ca

相关标签:
3条回答
  • 2020-11-29 12:02

    Answering the "what is the risk" question, the risk (or a risk) is running out of window handles, although it can take a while.

    I have a "window designer" that generates a window from a script. Each time I change the script, the window is rebuilt (the controls cleared and readded). With a particularly complex window, and using Controls.Clear() each time, after many dozens of refreshes, I will eventually get a "no more window handles" exception and not be able to create any more controls.

    Easy enough to replace the Controls.Clear() call with something like:

    Controls.Cast<Control>().ForEach(c => c.Dispose());
    
    0 讨论(0)
  • 2020-11-29 12:04

    Asking for modifications like this is pointless, the Windows Forms team has been disbanded quite a while ago. It is in maintenance mode, only security issues and OS incompatibilities are considered.

    It is otherwise simple enough to create your own method to do this:

      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);
          }
        }
      }
    

    Now you can write:

      panel1.Controls.Clear(true);
    
    0 讨论(0)
  • 2020-11-29 12:11

    @Hans Passant answer is good but in case of asynchronous programming you should consider to remove the object before dispose it to avoid some thread to iterate over a disposed object.

    More or less something like this:

    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();
        }
      }
    }
    
    0 讨论(0)
提交回复
热议问题