I have an ASP.NET site that I am maintaining. Currently it has code that on first access (and other times too) goes and does a bunch of data caching by writing it to files. Currently it has no locking so we cna get problems with multiple people accessing the site and multiple threads trying to write to the files at the same time. This is obviously bad so I am going to implement some locking.
My current modified code just puts a simple lock around a section of code so that later requests just wait until the first request is done.
My concern is that I haven't used locks much so I just want to check if there is any situation in which that lock could not get released? For example I have no idea what happens if that first thread is killed (eg the web server decides its run too long and shuts it down). Does the lock get automatically freed at that point? Is there anything else I need to think about while doing this?
Edit to add: Here is what I think are relevant bits of Code in case there is anything I am doing stupid...
I am using private lock objects accessed through a dictionary and don't do anything much more than wrap some code in a SyncLock statement (equivalent of 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
Should I wrap access to the GetCacheLockObject function in a lock to prevent the possibility of two threads going in simultaneously and both finding the cache lock doesn't exist and then both creating it and returning different ones? I'm a little unused to having to consider thread safeness (assumign I am using that term correctly).