线程是否在synclock上阻塞

时间:2015-03-27 00:52:46

标签: vb.net multithreading silverlight

我在从Silverlight调用的vb.net模块中获得了以下代码。它基本上在每个线程的基础上分配唯一的ID。

Public Module IdManager

Private _threadTrackingIds As New Dictionary(Of Integer, String)
Private _lockObject As New Object

Public Function GetNext() As String
    Dim threadId = System.Threading.Thread.CurrentThread.ManagedThreadId
    Dim g As String = Guid.NewGuid().ToString()
    SyncLock _lockObject
        _threadTrackingIds(threadId) = g
    End SyncLock
    Return g
End Function

Public ReadOnly Property CurrentTrackingID As String
    Get
        Dim threadId = System.Threading.Thread.CurrentThread.ManagedThreadId
        Dim idToReturn As String = String.Empty
        SyncLock _lockObject
            If (_threadTrackingIds.ContainsKey(threadId)) Then
                idToReturn = _threadTrackingIds(threadId)
            End If
        End SyncLock
        Return idToReturn
    End Get
End Property

End Module

GetNext()返回一个字符串,但在大多数情况下,我只是在不检查返回值的情况下调用它(即,只调用IdManager.GetNext()而不将其赋值给变量)因为我不知道需要这个值直到以后(有时候是其他方法)所以我只需要在需要时调用CurrentTrackingId。

但是,我有多个线程调用它(因此是synclock)所以我的问题是:如果它没有获得锁定,我的IdManager.GetNext()的调用代码将阻塞,或者它将继续进行直到它需要阻止?也就是说,我想知道如果不将字符串值赋给变量(即z = IdManager.GetNext()),然后可能使用该变量,会使调用者忽略它没有得到锁的事实。如果它没有阻止它,那么线程会继续执行其余的指令而不可能设置CurrentTrackingID吗?

1 个答案:

答案 0 :(得分:1)

是的,SyncLock通过只允许一个线程输入受保护的代码来提供同步。尝试在完全同时进入的任何其他线程将被阻止,直到锁定被释放。

实际发生这种情况的可能性非常低。但不是零。你持有锁很短的时间,字典是非常有效的,只需要一小部分微秒。你必须每秒数十万次调用这些方法来注意任何争用。

无需担心。如果绝对必要,你可以回退到ConcurrentDictionary,它使用更精细的锁并且更友好,因为你不必显式使用SyncLock。