mutiple threads calling the same function

I have an application that is running in 10 threads.  Each thread is calling the same functions and procedures.  I seem to have an issue where some threads might get duplicate results and they should not.  I would think the function would only return the value to the thread that called it, but looking at my results this is not always the case.  Can this happen if 2 threads call a function at the same time?  Is there a way to fix this?
Who is Participating?
If you can upgrade to .NET 4, you can use the Tasks in the new Parallel programming model in the framework.
Mike TomlinsonMiddle School Assistant TeacherCommented:
Do the functions make use of any class level variables (which would be shared across threads)?

Can we see the function?
chadmanvbAuthor Commented:
Thannks for the help.  I am calling a module in my form that contains a few funtions within it to get the user id of a user on a remote workstation.  I call getuser from this module:

Imports System.Management
Imports System.DirectoryServices
Imports Microsoft.Win32
Imports System.Runtime.InteropServices

Module UserInfo

    Dim objManagementClass As ManagementClass
    Dim objManagementScope As ManagementScope
    Dim objManagementBaseObject As ManagementBaseObject
    Public Function GetUser(ByVal RemotePC As String) As String

        Dim WMIScope As Management.ManagementScope
        Dim WMIConnectionOptions As New Management.ConnectionOptions
        Dim strRootDomain As String
        Dim objRootLDAP As DirectoryEntry
        Dim query As ManagementObjectSearcher
        Dim queryCollection As ManagementObjectCollection
        Dim oq As New System.Management.ObjectQuery
        Dim mo As New ManagementObject
        Dim UserDomain As String
        Dim UserID As String
        Dim StrLoggedUserSID() As Byte

        Dim Strcomputer As String = RemotePC 'My.Application.CommandLineArgs.Item(0)

        With WMIConnectionOptions
            .Impersonation = System.Management.ImpersonationLevel.Impersonate
            .Authentication = System.Management.AuthenticationLevel.Packet

        End With

        WMIScope = New Management.ManagementScope("\\" & _
        Strcomputer & "\root\cimv2", WMIConnectionOptions)

        objRootLDAP = New DirectoryEntry("LDAP://RootDSE")
        strRootDomain = objRootLDAP.Properties.Item("rootDomainNamingContext").Value.ToString

        oq = New System.Management.ObjectQuery("SELECT * from Win32_process Where Name='explorer.exe' and SessionID=0")
        query = New ManagementObjectSearcher(WMIScope, oq)
        queryCollection = query.Get()

        If queryCollection.Count = 0 Then
            Return ("Not logged in")
            Exit Function

            Dim strKeyPath As String = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon"
            objManagementScope = New ManagementScope
            objManagementScope.Path.Server = Strcomputer
            objManagementScope.Path.NamespacePath = "root\default"
            objManagementScope.Options.EnablePrivileges = True
            objManagementScope.Options.Impersonation = ImpersonationLevel.Impersonate

            objManagementClass = New ManagementClass("stdRegProv")
            objManagementClass.Scope = objManagementScope
            objManagementBaseObject = objManagementClass.GetMethodParameters("EnumValues")
            objManagementBaseObject.SetPropertyValue("hDefKey", CType("&H" & Hex(RegistryHive.LocalMachine), Long))
            objManagementBaseObject.SetPropertyValue("sSubKeyName", strKeyPath)

            UserDomain = CStr(GetRegValues("DefaultDomainName", strKeyPath, "HKLM"))
            UserID = CStr(GetRegValues("DefaultUserName", strKeyPath, "HKLM"))
            UserID = "DOMAIN\" & UserID
            Return (UserID)

            'If the SID or the full name is needed sometime in the future the code is below

            'If UCase(UserDomain) = UCase(strcomputer) Then
            'Console.WriteLine("Logged on user = " & UserDomain & "\" & UserID & " (local user)")
            'Exit Sub
            'End If

            'Dim LdapBind As String
            'LdapBind = ("LDAP://" & strRootDomain)

            'Dim deEntry3 As New DirectoryEntry(LdapBind)
            'Dim DSearch As New DirectorySearcher(deEntry3)

            'With DSearch
            '    .SearchScope = SearchScope.Subtree
            '    .Filter = "(&(objectclass=user)(sAMAccountName=" & UserID & "))"
            '    .PropertiesToLoad.Add("name")
            '    .PropertiesToLoad.Add("sAMAccountName")
            '    .PropertiesToLoad.Add("distinguishedName")
            'End With

            'Dim sResultSet As SearchResult

            'For Each sResultSet In DSearch.FindAll()

            '    If UCase(GetProperty(sResultSet, "sAMAccountName")) = UCase(UserID) Then

            '        Console.WriteLine("Logged on user = " & GetProperty(sResultSet, "name") & " (as " & _
            '        UserDomain & "\" & UserID & ")")

            '        Dim deEntry4 As New DirectoryEntry("LDAP://" & GetProperty(sResultSet, "distinguishedName").ToString)
            '        StrLoggedUserSID = CType(deEntry4.Properties("objectSid").Value, Byte())
            '        Console.WriteLine("User's SID = " & ConvertSid(StrLoggedUserSID))
            '    End If

        End If
    End Function

    Public Function GetProperty(ByVal srSearchResult As SearchResult, ByVal strPropertyName As String) As String
        If srSearchResult.Properties.Contains(strPropertyName) Then
            Return srSearchResult.Properties(strPropertyName)(0).ToString()
            Return String.Empty
        End If
    End Function
    Private Function GetRegValues(ByVal regkeyValue As String, ByVal regkey As String, ByVal Hive As String)

        Select Case Hive
            Case "HKLM"
                Hive = CStr(RegistryHive.LocalMachine)
            Case "HKU"
                Hive = CStr(RegistryHive.Users)
            Case "HKCU"
                Hive = CStr(RegistryHive.CurrentUser)
            Case "HKCR"
                Hive = CStr(RegistryHive.ClassesRoot)
        End Select

        objManagementBaseObject = objManagementClass.GetMethodParameters("GetStringValue")
        objManagementBaseObject.SetPropertyValue("hDefKey", CType("&H" & Hex(Hive), Long))
        objManagementBaseObject.SetPropertyValue("sSubKeyName", regkey)
        objManagementBaseObject.SetPropertyValue("sValueName", regkeyValue)
        objManagementBaseObject = objManagementClass.InvokeMethod("GetStringValue", objManagementBaseObject, Nothing)
        GetRegValues = objManagementBaseObject("sValue")

    End Function

    Public Function ConvertSid(ByVal sid As Byte()) As String

        Dim sidString As String
        Dim sidPtr As IntPtr
        Dim sidStringPtr As IntPtr
        Dim res As Integer

        sidPtr = Marshal.AllocHGlobal(sid.Length)
        Marshal.Copy(sid, 0, sidPtr, sid.Length)
        res = ConvertSidToStringSid(sidPtr, sidStringPtr)
        If res = 0 Then
            Throw New System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error())
        End If
        sidString = Marshal.PtrToStringAuto(sidStringPtr)

        Return sidString

    End Function

    <DllImport("advapi32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
    Private Function ConvertSidToStringSid(ByVal pSID As IntPtr, ByRef pSidString As IntPtr) As Integer
    End Function

End Module
Cloud Class® Course: Microsoft Office 2010

This course will introduce you to the interfaces and features of Microsoft Office 2010 Word, Excel, PowerPoint, Outlook, and Access. You will learn about the features that are shared between all products in the Office suite, as well as the new features that are product specific.

Mike TomlinsonMiddle School Assistant TeacherCommented:
I haven't worked with WMI enough to know if that code is safe or not for use across multiple threads...  =\
chadmanvbAuthor Commented:
Is there another way I can keep this running in mutiple threads?  The application is too slow to run in a single thread so I would like to keep it like this.  Chad
I am not sure if this would help but worth a try.

Create a class which contains two strings of machinename and username. Add the functions to the class to get the username and set the username property based on the machinename in the class. Then create a list of objects of this class, set the machinenames, and use threads on the methods in the objects. Or you may want to use a backgroundworker within the class to get the username.
chadmanvbAuthor Commented:
I still have not gotten this to work.  I am stuck using net 2.0 on the server I have to run this on.  Any other ideas how to make this call safe to use with mutiple threads?
chadmanvbAuthor Commented:
Could I also just I also make 10 modules and call them all separate names?  Then have each thread call a different one?  Currently I'm stuck running this in a single thread and it's taking to long.
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.