我有一个我正在维护的ASP.NET站点。目前,它具有首次访问(以及其他时间)的代码,并通过将其写入文件来执行大量数据缓存。目前它没有锁定,所以我们cna得到多个人访问该网站的问题和多个线程试图同时写入文件。这显然很糟糕,所以我要实现一些锁定。
我当前修改过的代码只是简单地锁定一段代码,以便后来的请求只等到第一个请求完成。
我担心的是我没有使用过很多锁,所以我只想检查是否存在无法释放该锁的情况?例如,我不知道如果第一个线程被杀死会发生什么(例如,Web服务器决定其运行时间过长并将其关闭)。锁定会在那时自动释放吗?这样做还有什么我需要考虑的吗?
编辑添加: 以下是我认为代码的相关部分,以防有什么事我做傻......
我正在使用通过字典访问的私有锁对象,并且除了在SyncLock语句中包含一些代码(相当于C#lock)之外,它不会做任何其他事情。
Public Shared Sub CheckAllVariables(ByVal SourceName As String, ByVal cn As HttpContext)
...
Do While dr.Read
projectID = dr.GetInt32(dr.GetOrdinal("ProjectID"))
Dim cacheLockObject As Object = GetCacheLockObject(projectID)
SyncLock (cacheLockObject)
srcName = String.Format("PROJECT_{0}", projectID)
If cacheCon.CheckNeeded(srcName) Then
RunFullCache(projectID, cn, Nothing)
CheckDerivedVariables(projectID, cn)
CheckHierarchyVariables(projectID, cn)
cn.Session(String.Format("DerivedChecked_{0}", projectID)) = True
projectNames.Add(srcName)
cacheCon.CheckNeeded(srcName) = False
End If
End SyncLock
Loop
...
End Sub
Private Shared CacheLockObjects As New Dictionary(Of Integer, Object)
Public Shared Function GetCacheLockObject(ByVal projectid As Integer) As Object
If Not CacheLockObjects.ContainsKey(projectid) Then
CacheLockObjects(projectid) = New Object()
End If
Return CacheLockObjects(projectid)
End Function
我是否应该锁定对锁中的GetCacheLockObject函数的访问,以防止两个线程同时进入的可能性,并且找不到缓存锁,然后创建它并返回不同的?我有点不习惯不得不考虑线程安全性(假设我正确使用该术语)。
答案 0 :(得分:3)
由于lock
只是Monitor
try { } finally { }
次来电,所以它不会被卡住。如果应用程序进入deadlock状态,应用程序可能会卡住。因此,在锁定多个对象时应该小心。
答案 1 :(得分:2)
如果要在运行CheckAllVariables的同时在其他地方添加ProjectID,则需要一个单独的锁来访问和使用CacheLockObjects字典。
您没有调用正在调用其他锁定机制的cacheLockObject内的任何功能。所以它看起来不像硬锁定是可能的。我同意如果线程在进程中被中止,你就不会有任何锁定问题。