Performance Problems!!

LeeSalter

Freshman
Joined
Feb 13, 2003
Messages
26
Location
In a House
Hello all. I hope that you can help me.

My application uses a tabbed form with around 200 controls in total.

It's basically an interface that displays information about UserID's in our NT Domain (or it will do soon..!).

The problem that I have is this.
A user is required to enter a UserID into an Input box which is fired from a menu.

Code:
Private Sub MenuItem4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItem4.Click

        Dim strPaycodeSearch As String
        Dim myUser As LANUser

        myUser = New LANUser(Me.lstbxUserShortcutsCurrentShortcuts, _
            Me.lstbxUsersGroupsUsersGroups)

        'Ask user for a user id
        strPaycodeSearch = InputBox("Please enter users paycode.", _
            "Enter paycode")

After some resetting of text boxes and checkoxes, the code then goes away and invokes a method in the LANUser class that uses the NetUserGetInfo API to return information into a USER_INFO_3 structure

Code:
Function GetUserDetails(ByRef UserID As String) As Boolean

        Dim UI3 As New USER_INFO_3()
        Dim Server As String
        Dim loopCount As Integer
        Dim lRet As Integer = -1
        Dim size As Integer = Marshal.SizeOf(UI3)
        Dim lpBuf As IntPtr = Marshal.AllocHGlobal(size)
        Dim Network As New Network()
        Const Level As Integer = 3

        _myShortcutBox.Items.Clear()

        Marshal.StructureToPtr(UI3, lpBuf, True)

        Server = Network.PDC & vbNullChar
        Me.UserID = UserID & vbNullChar

        lRet = NetUserGetInfo(Server, Me.UserID, Level, lpBuf)

        If lRet = NERR_SUCCESS Then

            UI3 = CType(Marshal.PtrToStructure(lpBuf, _
                     GetType(USER_INFO_3)), USER_INFO_3)

            Me.UserID = UI3.usri3_name
            Me.UserName = UI3.usri3_full_name
            Me.HomeServer = Microsoft.VisualBasic.Left(UI3.usri3_home_dir, 10)
            Me.HomeDirectory = UI3.usri3_home_dir
            Me.ProfilePath = UI3.usri3_profile
            Me.Description = UI3.usri3_comment
            Me.LogonScript = UI3.usri3_script_path
            Me.HomeDirectoryDrive = UI3.usri3_home_dir_drive
            Me.AccountFlags = UI3.usri3_flags

            NetApiBufferFree(lpBuf)
            Return True
        Else
            MessageBox.Show("User is not known to the PDC.")
            NetApiBufferFree(lpBuf)
            Return False
        End If

    End Function

If the Function succeeds, the form is updated with values taken from the LANUser proprties.

Code:
If myUser.GetUserDetails(strPaycodeSearch) = True Then

            Me.txtbxUserManagerDescription.Text = myUser.Description
            Me.txtbxUsersProfileProfilePath.Text = myUser.ProfilePath
            Me.txtbxUsersProfileLogonScript.Text = myUser.LogonScript
            Me.lblUserNamePaycode_ProfileTab.Text = myUser.UserID & " - " & _
                myUser.UserName
            Me.lblUserNamePaycode_UserTab.Text = myUser.UserID & " - " & _
                myUser.UserName
            Me.txtbxMoveUserHomeServer.Text = myUser.HomeServer
            Me.txtbxUsersHomeDirectoryConnectTo.Text = myUser.HomeDirectory
            Me.cmbbxUsersHomeDirectoryDrive.Text = myUser.HomeDirectoryDrive

            'Test to see if there is a valid profile on the users 
            'home server.

            If Directory.Exists(myUser.ProfilePath) = True Then
                myUser.ProfileExists = True
            Else
                myUser.ProfileExists = False
                MessageBox.Show("There does not appear to be a valid profile " & _
                    "on the server for this user.", "Profile Does Not Exist", _
                    MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
            End If

            'If a profile exists, retrieve the users shortcuts.

            If myUser.ProfileExists = True Then
                myUser.GetShortcuts(myUser.ProfilePath & "\Start Menu\", False)
                myUser.GetShortcuts(myUser.ProfilePath & "\Start Menu\Programs\Business\", True)
            End If

            'Get Account flags and set the Checkboxes on the forms
            Select Case myUser.AccountFlags
                Case 66049
                    myUser.PasswordNeverExpires = True
                    Me.chkbxUserManager_PasswordNeverExpires.Checked = True
                Case 577
                    myUser.PasswordCannotChange = True
                    Me.chkbxUserManager_UserCannotChangePassword.Checked = True
                Case 515
                    myUser.AccountDisabled = True
                    Me.chkbxUserManager_AccountDisabled.Checked = True
                Case 66113
                    myUser.PasswordCannotChange = True
                    myUser.PasswordNeverExpires = True
                    Me.chkbxUserManager_UserCannotChangePassword.Checked = True
                    Me.chkbxUserManager_PasswordNeverExpires.Checked = True
                Case 579
                    myUser.PasswordCannotChange = True
                    myUser.AccountDisabled = True
                    Me.chkbxUserManager_UserCannotChangePassword.Checked = True
                    Me.chkbxUserManager_AccountDisabled.Checked = True
                Case 66115
                    myUser.PasswordCannotChange = True
                    myUser.PasswordNeverExpires = True
                    myUser.AccountDisabled = True
                    Me.chkbxUserManager_UserCannotChangePassword.Checked = True
                    Me.chkbxUserManager_PasswordNeverExpires.Checked = True
                    Me.chkbxUserManager_AccountDisabled.Checked = True
                Case 66051
                    myUser.PasswordNeverExpires = True
                    myUser.AccountDisabled = True
                    Me.chkbxUserManager_PasswordNeverExpires.Checked = True
                    Me.chkbxUserManager_AccountDisabled.Checked = True
                Case 529
                    myUser.AccountLocked = True
                    Me.chkbxUserManager_AccountLockedOut.Checked = True
            End Select
End If

After this, the users NT Groups are acquired and populated into a listbox.

Code:
Public Function GetGroups(ByVal UserID As String) As Boolean
        Dim GI0 As New GROUP_USERS_INFO_0()
        Dim Level As Integer = 0
        Dim Network As New Network()
        Dim Server As String = Network.GetPDC & vbNullChar
        Dim i As Integer
        Dim lRet As Integer = -1
        Dim size As Integer = Marshal.SizeOf(GI0)
        Dim lpBuf As IntPtr = Marshal.AllocHGlobal(size)
        Dim EntriesRead As Integer
        Dim TotalEntries As Integer
        Dim lpBuf3 As IntPtr

        UserID = UserID & vbNullChar

        Marshal.StructureToPtr(GI0, lpBuf, True)

        lRet = NetUserGetGroups(Server, UserID, Level, lpBuf, -1, _
            EntriesRead, TotalEntries)

        If lRet = NERR_SUCCESS Then
            Dim nSize As Integer = Marshal.SizeOf(GI0)
            Dim lpBuf2 As IntPtr

            For i = 0 To EntriesRead - 1
                lpBuf2 = New IntPtr(lpBuf.ToInt32 + i * nSize)
                GI0 = CType(Marshal.PtrToStructure(lpBuf2, _
                          GetType(GROUP_USERS_INFO_0)), _
                          GROUP_USERS_INFO_0)

                _myGroupsbox.Items.Add(GI0.grui0_name)
            Next
            NetApiBufferFree(lpBuf)
            Return True
        Else
            NetApiBufferFree(lpBuf)
            Return False
        End If


    End Function

And that's it for now.
However, when I try to click on the menu again to pull up another users details, my application hangs and sometimes errors with a StackOverflowException.

This exception hits at the point where the Inputbox is supposed to be displayed. The new LANUser code is fired.

Apologies for the length of this post, but if anybody can tell me why this is happening, I'd be grateful.
 
A stack overflow exception is pretty much only thrown when your code is recursing on itself infinitely. Check for any actions in your code which could fire an event that runs the same code, this will be the problem 99% of the time.
 
Thanks Divil.

I think I may have narrowed this down a bit.
When I step through my code, the Click Event for my MenuItem sits on top of the stack.

When the End Sub command is processed in the Click Event, the process still sits on top of the stack. I was under the impression that when a method/process is finished with, it turns grey in the stack window.

When I click the menu item again, obviously the Click event from the previous instance is still active.

Any ideas why the Click event doesn't finish properly after the End Sub is processd??!!
 
I am guessing perhaps some code in the handler for this event does something which causes the Click event to get called in turn.
 
When your program gets the stack overflow, press "Break" then open the Call Stack window (Debug->Windows->Call Stack). You can see all the code executing up to the current error. Lines in black are your code, lines in light grey are .NET code (from DLLs and such). Look for the black lines. Chances are you'll see the same two or three functions/events firing over and over, calling each othe recursively.

-Nerseus
 
Back
Top