Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Weird, unexplained occurance...

Weird, unexplained occurance...

Scheduled Pinned Locked Moved C#
helpalgorithmsquestionannouncement
8 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    MarkB777
    wrote on last edited by
    #1

    I've been working on a CRS system, and was running into a nasty error... For some reason every ~16 or so search queries, the program would crash, and give me a WIN32 exception, telling me that my program had used up all its allocated handles. Ok, so I wasn't disposing of my objects correctly somewhere... After much searching, I found that the foreach loop that was disposing of the results was not working as expected. (the search results were displayed using Panels). If I called: int i = window.FlowPanel.Controls.Count; It would return the expected number of (say) 20. However when I ran: foreach (Control c in window.FlowPanel.Controls) { c.Dispose(); } It would cut out of the foreach loop at the 10th object. If I ran the same foreach loop directly afterwards, it would cut out at the 5th object etc etc. I solved the problem by using this snippet: while (window.FlowPanel.Controls.Count > 0) { foreach (Control c in window.FlowPanel.Controls) { c.Dispose(); } } GC.Collect(); This solved the problem, but can anyone explain this behaviour? Cheers, Mark.

    Mark Brock "We're definitely not going to make a G or a PG version of this. It's not PillowfightCraft." -- Chris Metzen

    OriginalGriffO G 2 Replies Last reply
    0
    • M MarkB777

      I've been working on a CRS system, and was running into a nasty error... For some reason every ~16 or so search queries, the program would crash, and give me a WIN32 exception, telling me that my program had used up all its allocated handles. Ok, so I wasn't disposing of my objects correctly somewhere... After much searching, I found that the foreach loop that was disposing of the results was not working as expected. (the search results were displayed using Panels). If I called: int i = window.FlowPanel.Controls.Count; It would return the expected number of (say) 20. However when I ran: foreach (Control c in window.FlowPanel.Controls) { c.Dispose(); } It would cut out of the foreach loop at the 10th object. If I ran the same foreach loop directly afterwards, it would cut out at the 5th object etc etc. I solved the problem by using this snippet: while (window.FlowPanel.Controls.Count > 0) { foreach (Control c in window.FlowPanel.Controls) { c.Dispose(); } } GC.Collect(); This solved the problem, but can anyone explain this behaviour? Cheers, Mark.

      Mark Brock "We're definitely not going to make a G or a PG version of this. It's not PillowfightCraft." -- Chris Metzen

      OriginalGriffO Offline
      OriginalGriffO Offline
      OriginalGriff
      wrote on last edited by
      #2

      It's not that unexplained - Think of it this way: If you have a list and you iterate through it, what happens when you delete one of the list entries? What is the next entry for an entry which has been deleted? What happens when the Controls list is traversed by a different process? Since foreach does effectively that - calls Controls.Next each time round the loop - it is very understandable that at some point you will have a problem. Normally, you would get a "Collection was modified; enumeration operation may not execute" exception, but I guess Dispose doesn't check that! Use Controls.Remove to take the controls out of the list, then Dispose them. You will need to need to modify the foreach to a for loop (and I suggest iterating backwards from the last to the first, to make it safer.) You will probably find you can rely on the frame work to do the dispose this way.

      No trees were harmed in the sending of this message; however, a significant number of electrons were slightly inconvenienced. This message is made of fully recyclable Zeros and Ones

      "I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
      "Common sense is so rare these days, it should be classified as a super power" - Random T-shirt

      G M 2 Replies Last reply
      0
      • M MarkB777

        I've been working on a CRS system, and was running into a nasty error... For some reason every ~16 or so search queries, the program would crash, and give me a WIN32 exception, telling me that my program had used up all its allocated handles. Ok, so I wasn't disposing of my objects correctly somewhere... After much searching, I found that the foreach loop that was disposing of the results was not working as expected. (the search results were displayed using Panels). If I called: int i = window.FlowPanel.Controls.Count; It would return the expected number of (say) 20. However when I ran: foreach (Control c in window.FlowPanel.Controls) { c.Dispose(); } It would cut out of the foreach loop at the 10th object. If I ran the same foreach loop directly afterwards, it would cut out at the 5th object etc etc. I solved the problem by using this snippet: while (window.FlowPanel.Controls.Count > 0) { foreach (Control c in window.FlowPanel.Controls) { c.Dispose(); } } GC.Collect(); This solved the problem, but can anyone explain this behaviour? Cheers, Mark.

        Mark Brock "We're definitely not going to make a G or a PG version of this. It's not PillowfightCraft." -- Chris Metzen

        G Offline
        G Offline
        Greg Chelstowski
        wrote on last edited by
        #3

        You're changing the collection you're iterating through-- So the object you started off with at the beginning of the loop is not the same one at the end. I'm surprised it even let you do that... a

        for(int x=FlowPanel.Controls.Count-1; x>=0; x--)
        {
        FlowPanel.Controls(x).Dispose();
        }

        should do the trick, I think.

        var question = (_2b || !(_2b));

        OriginalGriffO M 2 Replies Last reply
        0
        • OriginalGriffO OriginalGriff

          It's not that unexplained - Think of it this way: If you have a list and you iterate through it, what happens when you delete one of the list entries? What is the next entry for an entry which has been deleted? What happens when the Controls list is traversed by a different process? Since foreach does effectively that - calls Controls.Next each time round the loop - it is very understandable that at some point you will have a problem. Normally, you would get a "Collection was modified; enumeration operation may not execute" exception, but I guess Dispose doesn't check that! Use Controls.Remove to take the controls out of the list, then Dispose them. You will need to need to modify the foreach to a for loop (and I suggest iterating backwards from the last to the first, to make it safer.) You will probably find you can rely on the frame work to do the dispose this way.

          No trees were harmed in the sending of this message; however, a significant number of electrons were slightly inconvenienced. This message is made of fully recyclable Zeros and Ones

          G Offline
          G Offline
          Greg Chelstowski
          wrote on last edited by
          #4

          Damnit, beat me to the punch. ;)

          var question = (_2b || !(_2b));

          1 Reply Last reply
          0
          • G Greg Chelstowski

            You're changing the collection you're iterating through-- So the object you started off with at the beginning of the loop is not the same one at the end. I'm surprised it even let you do that... a

            for(int x=FlowPanel.Controls.Count-1; x>=0; x--)
            {
            FlowPanel.Controls(x).Dispose();
            }

            should do the trick, I think.

            var question = (_2b || !(_2b));

            OriginalGriffO Offline
            OriginalGriffO Offline
            OriginalGriff
            wrote on last edited by
            #5

            Sorry about beating you to it - it was just luck - but I still think using Remove from the controls list will be a better solution than Dispose!

            No trees were harmed in the sending of this message; however, a significant number of electrons were slightly inconvenienced. This message is made of fully recyclable Zeros and Ones

            "I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
            "Common sense is so rare these days, it should be classified as a super power" - Random T-shirt

            G 1 Reply Last reply
            0
            • OriginalGriffO OriginalGriff

              Sorry about beating you to it - it was just luck - but I still think using Remove from the controls list will be a better solution than Dispose!

              No trees were harmed in the sending of this message; however, a significant number of electrons were slightly inconvenienced. This message is made of fully recyclable Zeros and Ones

              G Offline
              G Offline
              Greg Chelstowski
              wrote on last edited by
              #6

              OriginalGriff wrote:

              Remove from the controls list will be a better solution than Dispose!

              Agreed, no arguments there. Didn't think it through completely ;>

              var question = (_2b || !(_2b));

              1 Reply Last reply
              0
              • OriginalGriffO OriginalGriff

                It's not that unexplained - Think of it this way: If you have a list and you iterate through it, what happens when you delete one of the list entries? What is the next entry for an entry which has been deleted? What happens when the Controls list is traversed by a different process? Since foreach does effectively that - calls Controls.Next each time round the loop - it is very understandable that at some point you will have a problem. Normally, you would get a "Collection was modified; enumeration operation may not execute" exception, but I guess Dispose doesn't check that! Use Controls.Remove to take the controls out of the list, then Dispose them. You will need to need to modify the foreach to a for loop (and I suggest iterating backwards from the last to the first, to make it safer.) You will probably find you can rely on the frame work to do the dispose this way.

                No trees were harmed in the sending of this message; however, a significant number of electrons were slightly inconvenienced. This message is made of fully recyclable Zeros and Ones

                M Offline
                M Offline
                MarkB777
                wrote on last edited by
                #7

                Thanks! :)

                Mark Brock "We're definitely not going to make a G or a PG version of this. It's not PillowfightCraft." -- Chris Metzen

                1 Reply Last reply
                0
                • G Greg Chelstowski

                  You're changing the collection you're iterating through-- So the object you started off with at the beginning of the loop is not the same one at the end. I'm surprised it even let you do that... a

                  for(int x=FlowPanel.Controls.Count-1; x>=0; x--)
                  {
                  FlowPanel.Controls(x).Dispose();
                  }

                  should do the trick, I think.

                  var question = (_2b || !(_2b));

                  M Offline
                  M Offline
                  MarkB777
                  wrote on last edited by
                  #8

                  Thanks! :-)

                  Mark Brock "We're definitely not going to make a G or a PG version of this. It's not PillowfightCraft." -- Chris Metzen

                  1 Reply Last reply
                  0
                  Reply
                  • Reply as topic
                  Log in to reply
                  • Oldest to Newest
                  • Newest to Oldest
                  • Most Votes


                  • Login

                  • Don't have an account? Register

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • World
                  • Users
                  • Groups