Results 1 to 12 of 12

Thread: My.Settings Issue with System.Collections.Specialized.StringCollection

  1. #1

    Thread Starter
    Junior Member
    Join Date
    Oct 2008
    Posts
    16

    My.Settings Issue with System.Collections.Specialized.StringCollection

    Hey everyone, i try not to post many questions. I tend to want to figure things out on my own but this is got me stumped. I've down some searching on the forums and on google with not much luck.

    Basically i have a System.Collections.Specialized.StringCollection in My.Settings. Currently it has 21 entries in this format:

    "NickName,Filename"

    I'm trying to populate a listbox on my form startup and i'm using this sub.

    I'm not sure why but it stops at number 8 in the list, doesn't give any type of error in the debug output. I've stepped through the Sub manually and after it hits #8 it just exits the for loop. At the time it exits the loop my count = 21 and i = 7.

    Any idea's on why this might be happening?



    Code:
     Private Sub PopulateListBox()
            Dim count As Integer = My.Settings.downloadedservers.Count
            For i = 0 To count
                Dim servername As String = My.Settings.downloadedservers.Item(i).Split(",").GetValue(0)
                Dim serverfilename As String = My.Settings.downloadedservers.Item(i).Split(",").GetValue(1)
                If ListBox1.Items.Contains(servername) Then
                    Return
                Else
                    ListBox1.Items.Add(servername)
                End If
    
            Next
    
        End Sub

  2. #2
    You don't want to know.
    Join Date
    Aug 2010
    Posts
    4,578

    Re: My.Settings Issue with System.Collections.Specialized.StringCollection

    I can think of two reasons.

    1. One of the items (#8) does not contain a "," character, so there is no 2nd element and trying to access it to find 'serverfilename' throws an exception.
    2. There are duplicate servers in the list, #8 is the first duplicate, and the "Return" statement does what it says: "This Sub is finished."

    If it's (1), you need to make sure all of your items have commas, and you also need to make your code robust enough to handle entries that don't have commas.

    If it's (2), you probably meant to use "Continue For" instead of "Return".

    Either way, it's silly to duplicate so much effort. Every time you access .Item(i), the computer does work. Every time you call Split(","), the computer does work. And since you typed it twice, it's clutter. Consider this implementation:
    Code:
    Private Sub PopulateListBox()
        Dim count As Integer = My.Settings.downloadedservers.Count
        For i = 0 To count
            Dim thisServer As String = My.Settings.downloadedservers(i)
            Dim tokens() As String = thisServer.Split(",")
            If tokens.Length <> 2 Then
                Console.WriteLine("The server '{0}' is improperly formatted.", thisServer)
                Continue For
            End If 
    
            Dim serverName As String = tokens(0)
            If ListBox1.Items.Contains(serverName) Then
                Console.WriteLine("The server '{0}' is a duplicate.", serverName)
                Continue For
            End If
    
            ListBox1.Items.Add(serverName)
        Next
    End Sub
    This is more robust, less cluttered, and tells you what went wrong if either of the obvious errors happens.
    This answer is wrong. You should be using TableAdapter and Dictionaries instead.

  3. #3
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    38,989

    Re: My.Settings Issue with System.Collections.Specialized.StringCollection

    Just to expand a bit on Sitten's #1 point: You think there is no error, but your description fits this perfectly. If you stepped through the code and hit the Return statement (Sitten's #2 point), you'd have seen that. The fact that it "just exits" is very telling, as that is almost certainly the first case, and the reason you are seeing no error messages is that the method is being called from the Load event handler. In some 64-bit systems (maybe most, or even all), an exception thrown in the Load event handler (or any method called from it), and not caught in the event handler, will simply be swallowed. That's exactly what you described.

    So, in other words: You are getting an exception, but the method is called from the Load event handler, so it is being swallowed without you seeing it. Wrap the code in a Try...Catch block and do something with the exception so you can see it and it will be there.
    My usual boring signature: Nothing

  4. #4
    You don't want to know.
    Join Date
    Aug 2010
    Posts
    4,578

    Re: My.Settings Issue with System.Collections.Specialized.StringCollection

    And also: "Never use the Load event handler again, it's a trap designed to hurt people because MS is sadistic 'for historical reasons'. Use Shown from this day forth, it's the event that behaves like Load did before it broke."
    This answer is wrong. You should be using TableAdapter and Dictionaries instead.

  5. #5
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    38,989

    Re: My.Settings Issue with System.Collections.Specialized.StringCollection

    I like the constructor, myself. Of course, that gets called at a different time, so there are added advantages/disadvantages to that one.
    My usual boring signature: Nothing

  6. #6
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,299

    Re: My.Settings Issue with System.Collections.Specialized.StringCollection

    Quote Originally Posted by Sitten Spynne View Post
    Use Shown from this day forth, it's the event that behaves like Load did before it broke.
    But it's not, because Shown is raised after the form is displayed, while Load is raised before it's displayed. If you put code that runs for any appreciable time in Shown then the user will see a frozen form. Shown was added because people didn't want to have to handle Activated and add code to test for just the first occurrence. Load should be used as it always was. Everyone just needs to learn the lesson that unhandled exceptions in that event handler will be swallowed on most systems these days. It's far from the only lesson a developer needs to learn.

  7. #7
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    38,989

    Re: My.Settings Issue with System.Collections.Specialized.StringCollection

    That's not quite true, and I'm not sure why not. I have an application that has an extensive amount of work to do during startup. At first, I divided the work into three parts. That which had nothing to do with the form controls went into the constructor. A second part went into the Load event, and a third part was supposed to happen after the form was fully loaded, so that was put into the Shown event. What I found was that the form was actually rendered to the screen AFTER the Shown event. Normally, this doesn't matter, since rendering is typically pretty fast, but in this case it caused some terrible visual tearing effects.

    However, I basically agree: Just be aware of the potential consequence of an exception in the Load event. It's easy enough to deal with, but annoying, because the behavior can be SO bizarre if that exception doesn't get handled.

    By the way, I heard a rumor that this was fixed such that it will cease to be an issue on newer systems (perhaps Win10?), but I have yet to see or hear any confirmation of that.
    My usual boring signature: Nothing

  8. #8
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,299

    Re: My.Settings Issue with System.Collections.Specialized.StringCollection

    Quote Originally Posted by Shaggy Hiker View Post
    By the way, I heard a rumor that this was fixed such that it will cease to be an issue on newer systems (perhaps Win10?), but I have yet to see or hear any confirmation of that.
    I just tested some code in the latest version of VS on the latest version of Windows 10 that should have thrown a DivideByZeroException in the Load event handler and it appeared to be swallowed.

  9. #9
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,299

    Re: My.Settings Issue with System.Collections.Specialized.StringCollection

    Quote Originally Posted by Shaggy Hiker View Post
    That's not quite true, and I'm not sure why not. I have an application that has an extensive amount of work to do during startup. At first, I divided the work into three parts. That which had nothing to do with the form controls went into the constructor. A second part went into the Load event, and a third part was supposed to happen after the form was fully loaded, so that was put into the Shown event. What I found was that the form was actually rendered to the screen AFTER the Shown event. Normally, this doesn't matter, since rendering is typically pretty fast, but in this case it caused some terrible visual tearing effects.
    I just put calls to MessageBox.Show in the Load event handler and the Shown event handler and the form itself was displayed after the first message and before the second. Maybe it depends what code you have and whether it renders anything on-screen, so the form will be rendered before anything else but if there's no other rendering code then the form comes last.

  10. #10
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    38,989

    Re: My.Settings Issue with System.Collections.Specialized.StringCollection

    Quote Originally Posted by jmcilhinney View Post
    I just tested some code in the latest version of VS on the latest version of Windows 10 that should have thrown a DivideByZeroException in the Load event handler and it appeared to be swallowed.
    Darn! Spurious information, I guess. Oh well, we'd still have to live with it for a long time, anyways, since systems that would show the behavior will remain common for years.
    My usual boring signature: Nothing

  11. #11
    You don't want to know.
    Join Date
    Aug 2010
    Posts
    4,578

    Re: My.Settings Issue with System.Collections.Specialized.StringCollection

    When it's JMC, Shaggy Hiker, and me sitting at the table, I'm going to agree with all these technical nuances. My experience is Load happens "after the form is on the screen" and Shown happens "before it is on the screen". My experience is also that "on the screen" can mean different things based on a myriad of factors. We all understand exactly when and why Load has problems, and we all know we should be catching/logging exceptions anyway. We've probably also all been burned by it hundreds of times.

    But I don't really give a flip about whether the form appears before, after, or during Load/Shown. (My experience is the exact timing varies depending on several factors.) If I have 10s of startup code to execute, I find "10 seconds of blank screen" to be just as amateurish as "10 seconds of frozen UI". I offload that work to a worker thread and display a "Loading" indicator. You should be too. We're long-time veterans and we're above leaving our users wondering if the app's ever going to show up, that's a strong opinion strongly held.

    So I like to tell newbies "use Shown, not Load". Any expert can immediately understand and explain that problem, and most novices have a grasp of it too. If it leads to the problem "my form is displayed too early and freezes" any expert can explain how to perform initialization on another thread. The only reason "Load swallows exceptions" gets answered is we tend to look for it out of habit. Few novices and not all experts have developed that particular habit, particularly if they've never had to deal with x64 machines.

    I like to guide newbies to things that work without memorizing silly details about the computer.
    This answer is wrong. You should be using TableAdapter and Dictionaries instead.

  12. #12
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    38,989

    Re: My.Settings Issue with System.Collections.Specialized.StringCollection

    Quote Originally Posted by jmcilhinney View Post
    I just put calls to MessageBox.Show in the Load event handler and the Shown event handler and the form itself was displayed after the first message and before the second. Maybe it depends what code you have and whether it renders anything on-screen, so the form will be rendered before anything else but if there's no other rendering code then the form comes last.
    There is some interesting rendering going on in my form, since it uses XNA to draw many of the controls. However, nothing much is actually done in the Shown event handler.

    What I was doing was putting up a full-screen form as a false front. The setup happened behind the scenes of that form, including the creation of the main form. What I thought was that I could show the main form behind the (TopMost) facade screen. Therefore, the facade screen handled the main form Shown event, and would go away once that event was received, thereby revealing the main form behind it in all its glory....or, at least, that's what I had expected to happen.

    What actually happened was that the facade screen went away to reveal the main form still being rendered. The solution was to run a timer in the facade form. When the main form Shown event was raised, the timer would start, run for a second or two, and THEN the facade form would disappear, thus revealing the main form, which by then had finished rendering. This worked fine.

    So, I'm not sure what the exact sequence is. I'm also not sure why that one or two seconds is even necessary. The XNA rendering is really fast. After all, the program allows for zooming, which causes almost the same redraw as the initial rendering, but which takes no noticeable time. Perhaps the XNA is setting up some bitmaps during that initial rendering time, which thereafter reside in video memory, but the result is that I have to wait a second or two before dropping the curtain if I don't want to reveal the main form still pulling on it's costume.
    My usual boring signature: Nothing

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width