C# lock internal implementation - c#

I know that now in C# lock is implemented in such way:
bool lockWasTaken = false;
var temp = obj;
try
{
Monitor.Enter(temp, ref lockWasTaken);
{
//body
}
}
finally
{
if (lockWasTaken)
{
Monitor.Exit(temp);
}
}
Why do we need this: var temp = obj; ?

Simple, What if you changed the variable after the Monitor.Enter called and before Monitor.Exit?
To prevent that it takes up a copy of the variable. Even you can set the value to null also inside the lock statement but still it makes sure that it releases the lock which it taken earlier.

Because obj might be reassigned within the body of the lock code, and the code you've shown has to make sure that it calls Exit on the same object it called Enter for.

Related

memory management impact on setting objects to null in finally

public void func1()
{
object obj= null;
try
{
obj=new object();
}
finally
{
obj = null;
}
}
is there any advantage of assigning null to a reference in finally block in regards of memory management of large objects?
Let's deal with the explicit and implicit questions here.
Q: First and foremost, is there a point in assigning null to a local variable when you're done with it?
A: No, none at all. When compiled with optimizations and not running under a debugger, the JITter knows the segment of the code where a variable is in use and will automatically stop considering it a root when you've passed that segment. In other words, if you assign something to a variable, and then at some point never again read from it, it may be collected even if you don't explicitly set it to null.
So your example can safely be written as:
public void func1()
{
object obj = new object();
// implied more code here
}
If no code in the "implied more code here" ever accesses the obj variable, it is no longer considered a root.
Note that this changes if running in a non-optimized assembly, or if you hook up a debugger to the process. In that case the scope of variables is artificially extended until the end of their scope to make it easier to debug.
Q: Secondly, what about fields in the surrounding class?
A: Here it can definitely make a difference.
If the object surrounding your method is kept alive for an extended period of time, and the need for the contents of a field has gone, then yes, setting the field to null will make the old object it referenced eligible for collection.
So this code might have merit:
public class SomeClass
{
private object obj;
public void func1()
{
try
{
obj=new object();
// implied more code here
}
finally
{
obj = null;
}
}
}
But then, why are you doing it like this? You should instead strive to write cleaner code that doesn't rely on surrounding state. In the above code you should instead refactor the "implied more code here" to be passed in the object to use, and remove the global field.
Obviously, if you can't do that, then yes, setting the field to null as soon as its object reference is no longer needed is a good idea.
Fun experiment, if you run the below code in LINQPad with optimizations on, what do you expect the output to be?
void Main()
{
var s = new Scary();
s.Test();
}
public class Scary
{
public Scary()
{
Console.WriteLine(".ctor");
}
~Scary()
{
Console.WriteLine("finalizer");
}
public void Test()
{
Console.WriteLine("starting test");
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
Console.WriteLine("ending test");
}
}
Answer (mouseover to show when you think you've got it):
.ctor
starting test
finalizer
ending test
Explanation:
Since the implicit this parameter to an instance method is never used inside the method, the object surrounding the method is collected, even if the method is currently running.

How to acquire multiple locks in VS2012 without messing up indentation

This looks like a silly question, but I'm not able to find a solution to this.
My problem is that C# doesn't allow for the acquisition of multiple locks in a single lock statement. This won't work:
lock (a, b, c, d)
{
// ...
}
Instead, it seems to require an insane amount of indentation in order to do this:
lock (a)
lock (b)
lock (c)
lock (d)
{
// ...
}
Coupled with all other indentation levels that the code is already in (namespaces, class, method, conditionals, loops, ...), this gets insane. So instead, I want to use this formatting:
lock (a) lock (b) lock (c) lock (d)
{
// ...
}
and preserve my sanity. But Visual Studio (I'm using 2012) won't hear of it. As soon as I enter any closing brace, the above is transformed to something silly, like:
lock (a) lock (b) lock (c) lock (d)
{
// ...
}
And there seems there's nothing I can do. Is there any way to make this work?
Just an idea :- )
static class LockAndExecute
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static void _gen(Action a, object[] objs, int i = 0){
bool lockWasTaken = false;
var temp = objs[i];
try {
Monitor.Enter(temp, ref lockWasTaken);
if(i + 1 >= objs.Length)
a();
else
_gen(a, objs, i + 1);
}
finally
{
if (lockWasTaken)
Monitor.Exit(temp);
}
}
public static void Do(object[] objectsToLock, Action action){
_gen(action, objectsToLock);
}
}
and the usage;
LockAndExecute.Do(new[]{a, b}, () => {
Console.WriteLine("Eww!");
});
Using that many locks at a time is just asking for deadlock. Heck, even acquiring two different locks at a time runs that risk.
At the very least, you should be very very careful to only ever take these locks in exactly the same order everywhere that more than one is acquired at a time.
Also, "nice formatting" is in the eye of the beholder. That is, everyone's got their own idea of what's best. But, the following should work, without VS messing with it unless you specifically ask it to (e.g. by triggering an auto-format rule or explicitly auto-formatting):
lock (a)
lock (b)
lock (c)
lock (d)
{
}
You can also use this approach with using statements (where it's much more common to have more than one in a row), where the VS IDE already anticipates it.
You could work around the IDE's annoying behavior by changing your code, though the idea of changing your code to work around IDE behavior pains my conscience a little. I'd do it if it was a toy project but not on anything serious that another developer might work on.
Implement the lock with an IDisposable implementation. The using statement does not have the annoying indentation issue that the lock statements do.
class myLock : IDisposable
{
private object _obj;
public myLock(object obj)
{
_obj = obj;
System.Threading.Monitor.Enter(obj);
}
public void Dispose()
{
System.Threading.Monitor.Exit(_obj);
_obj = null;
}
public static void example()
{
var obj1 = new object();
var obj2 = new object();
var obj3 = new object();
lock (obj1)
lock (obj2)
lock (obj3)
{
// Stupid indentation >:(
}
using (new myLock(obj1))
using (new myLock(obj2))
using (new myLock(obj3))
{
// Ahhhh... :-)
}
}
}

Asp.Net caching pattern

There are a great number of articles available regarding thread safe caching, here's an example:
private static object _lock = new object();
public void CacheData()
{
SPListItemCollection oListItems;
oListItems = (SPListItemCollection)Cache["ListItemCacheName"];
if(oListItems == null)
{
lock (_lock)
{
// Ensure that the data was not loaded by a concurrent thread
// while waiting for lock.
oListItems = (SPListItemCollection)Cache[“ListItemCacheName”];
if (oListItems == null)
{
oListItems = DoQueryToReturnItems();
Cache.Add("ListItemCacheName", oListItems, ..);
}
}
}
}
However, this example depends on the request for the cache also rebuilding the cache.
I'm looking for a solution where the request and rebuild are separate. Here's the scenario.
I have a web service that I want to monitor for certain types of error. If an error occurs, I create an monitor object and cache - it is updatable and is locked accordingly during update. Alls well so far.
Elsewhere, I check for the existence of the cached object, and the data it contains. This would work straight out of the box except for one particular scenario.
If the cache object is being updated - say a status change, I would like to wait and get the latest info rather than the current info, which if returned, would be out of date. So for my fetch code, I need to check if the object is currently being created/updating, and if so wait, then retry.
As I pointed out, there are many examples of cache locking patterns but I can't seem to find one that for this scenario. Any ideas as to how to go about this would be appreciated?
You can try the following code using two locks. Write lock in the setter is quite simple and protects cache from being written by more than one threads. The getter use a simple double-check lock.
Now, the trick is in Refresh() method, which uses the same lock as the getter. The method uses the lock and in the first step removes list from the cache. It will trigger any getter to fail the first null check and wait for the lock. The method in the meantime gets items, sets cache again and releases the lock.
When it comes back to the getter, it reads the cache again and now it contains the list.
public class CacheData
{
private static object _readLock = new object();
private static object _writeLock = new object();
public SPListItemCollection ListItem
{
get
{
var oListItems = (SPListItemCollection) Cache["ListItemCacheName"];
if (oListItems == null)
{
lock (_readLock)
{
oListItems = (SPListItemCollection)Cache["ListItemCacheName"];
if (oListItems == null)
{
oListItems = DoQueryToReturnItems();
Cache.Add("ListItemCacheName", oListItems, ..);
}
}
}
return oListItems;
}
set
{
lock (_writeLock)
{
Cache.Add("ListItemCacheName", value, ..);
}
}
}
public void Refresh()
{
lock (_readLock)
{
Cache.Remove("ListItemCacheName");
var oListItems = DoQueryToReturnItems();
ListItem = oListItems;
}
}
}
You can make the method and property static, if you do not need CacheData instance.

Is this a valid object disposal code pattern in method with return?

I noticed the following object disposal code pattern in a C# project and I was wondering if it's acceptable (although it works).
public object GetData()
{
object obj;
try
{
obj = new Object();
// code to populate SortedList
return obj;
}
catch
{
return null;
}
finally
{
if (obj != null)
{
obj.Dispose();
obj = null;
}
}
}
For this example, I'm using a general 'object' instead of the actual IDisposable class in the project.
I know that the 'finally' block will be executed every time, even when the value is returned, but would it affect the return value (or would it be a new object instance) in any way since the object is being set to null (for what seems like object disposal and GC purposes).
Update 1:
I tried the following snippet and the return object is non-null, although the local object is set to null, so it works, which is a bit strange considering some of the comments below:
public StringBuilder TestDate()
{
StringBuilder sb;
try
{
sb = new StringBuilder();
sb.Append(DateTime.UtcNow.ToString());
return sb;
}
catch
{
return null;
}
finally
{
sb = null;
}
}
Btw, I'm using C# 4.0.
P.S. I'm just reviewing this project code. I'm not the original author.
Update 2:
Found the answer to this mystery [1]. The finally statement is executed, but the return value isn't affected (if set/reset in the finally block).
[1] What really happens in a try { return x; } finally { x = null; } statement?
This code will compile fine (assuming that you are not actually using an Object but something that implements IDisposable), but it probably won't do what you want it to do. In C#, you don't get a new object without a new; this code will return a reference to an object that has already been disposed, and depending on the object and what Dispose() actually does, trying to use a disposed object may or may not crash your program.
I assume the idea is to create an object, do some stuff with it, then return the object if successful or null (and dispose the object) on failure. If so, what you should do is:
try {
obj = new MyClass();
// ... do some stuff with obj
return obj;
}
catch {
if(obj != null) obj.Dispose();
return null;
}
Simply using the using statement achieves the same result as that, and is the standard practice
public int A()
{
using(IDisposable obj = new MyClass())
{
//...
return something;
}
}
I would, however, advise against returning your IDisposable object.
When you dispose of an object, it is supposed to be considered "unusable". And so, why return it?
If the object's lifetime needs to be longer than the method A's lifetime, consider having the calling method B instantiate the object, and pass it as a parameter to method A.
In this case, method Bwould be the one using the using statement, inside which it would call A.
If you are returning an IDisposable object, then it is the responsibility of your caller to dispose of it:
public IDisposable MakeDisposableObject()
{
return new SqlConnection(""); // or whatever
}
caller:
using (var obj = MakeDisposableObject())
{
}
It makes less than no sense for your method to dispose of an object and then return it. The disposed object will be of no value to the caller. In general, referencing a disposable object which has been disposed should produce an ObjectDisposedException.
A few observations.
That code wouldn't compile because object doesn't have a .Dispose() method.
Why wouldn't you use IDisposable?
Why would you dispose of an object that is being returned, since returning you would return an object for the purpose of some other code to use it. The concept of "disposing" of something is to give it a chance to clean up after itself and its used, un-managed resources. If you are returning an object that is supposed to be used elsewhere, but has unmanaged resources that you want to clean up before the object gets used anywhere else, then you shuld really have 2 separate objects. One to load some data that would be disposable, and another object that would contain the usable loaded content that you want to pass around. An example of this would be something like stream readers in the .NET framework. You would normally new a stream reader, read it into a byte[] or some other data object, .Dispose() the stream reader, then return the byte[]. The "loader" that has some resources to dispose of in a timely fashion is separate from the object containing the "loaded" data that can be used without needing to be disposed.

Error with ReaderWriterLockSlim

I got this exception
The read lock is being released without being held.
at System.Threading.ReaderWriterLockSlim.ExitReadLock()
at .. GetBreed(String)
Below is the only place in code that accesses the lock. As you can see, there is no recursion. I'm having trouble understanding how this exception could occur.
static readonly Dictionary<string, BreedOfDog> Breeds
= new Dictionary<string,BreedOfDog>();
static BreedOfDog GetBreed(string name)
{
try
{
rwLock.EnterReadLock();
BreedOfDog bd;
if (Breeds.TryGetValue(name, out bd))
{
return bd;
}
}
finally
{
rwLock.ExitReadLock();
}
try
{
rwLock.EnterWriteLock();
BreedOfDog bd;
//make sure it hasn't been added in the interim
if (Breeds.TryGetValue(t, out bd)
{
return bd;
}
bd = new BreedOfDog(name); //expensive to fetch all the data needed to run the constructor, hence the caching
Breeds[name] = bd;
return bd;
}
finally
{
rwLock.ExitWriteLock();
}
}
I'm guessing you have something re-entrant, and it is throwing an exception when obtaining the lock. There is a catch-22 whether you "take the lock", "try" vs "try", "take the lock", but the "take the lock", "try" has fewer failure cases (the "aborted between take and try" is so vanishingly unlikely you don't need to stress).
Move the "take the lock" outside the "try", and see what the actual exception is.
The problem is most likely that you are failing to take the lock (probably re-entrancy), then trying to unlock something you didn't take. This could mean that the exception surfaces in the orginal code that took the lock, due to trying to release twice when only taken once.
Note: Monitor has new overloads with "ref bool" parameters to help with this scenario - but not the other lock types.
Use LockRecursionPolicy.SupportsRecursion when instantiating the RWLS. If the error goes away then you actually do have some type of recursion involved. Perhaps it is in code that you did not post?
And if you are really concerned about getting maximum concurrency out of this (as I suspect you are since you are using a RWLS) then you could use the double-checked locking pattern. Notice how your original code already has that feel to it? So why beat around bush? Just do it.
In the following code notice how I always treat the Breeds reference as immutable and then inside the lock I recheck, copy, change, and swap out the reference.
static volatile Dictionary<string, BreedOfDog> Breeds = new Dictionary<string,BreedOfDog>();
static readonly object LockObject = new object();
static BreedOfDog GetBreed(string name)
{
BreedOfDog bd;
if (!Breeds.TryGetValue(name, out bd))
{
lock (LockObject)
{
if (!Breeds.TryGetValue(name, out bd))
{
bd = new BreedOfDog(name);
var copy = new Dictionary<string, BreedOfDog>(Breeds);
copy[name] = bd;
Breeds = copy;
}
}
}
return bd;
}

Categories