I have the following code:
public class Settings
{
private object _lock = new object();
public void Save() {
lock (_lock)
{
...
}
}
}
On windows 8 x86 / .net 4.0 lock throws exception:
Exception Type: System.ArgumentNullException
Exception Message: Value cannot be null.
Exception Target Site: ReliableEnter
I attached debugger and its null. _lock is really null :|
On windows 7 x64 it works all right. I am checking other OSes now.
EDIT:
It is realted to deserialization. After deserialization of Settings class _lock is null. _lock field didn't exist at the time of serilization of settings and its getting back deserialized as null. Deleting serilized object file and recreating it with lock field eliminated exception. I will check if this is correct deserialization behavior if field didin't exist at serialization. Overwriting object value initialized in declaration doesn't look cool to me. But thats pretty much answer to this. I admit that I didn't consider serialization, deserialization at the time I asked for help ;).
EDIT2: Here is the code that ilustrates my scenario and what was happening to me:
Serilize class without _lock field
class Program { static void Main(string[] args) { Settings set = new Settings(); using (FileStream fs = new FileStream(@"C:\test\tst.set", FileMode.Create, FileAccess.Write, FileShare.None)) { BinaryFormatter bf = new BinaryFormatter(); bf.Serialize(fs, set); fs.Flush(); fs.Close(); } } } [Serializable] internal class Settings { private int _i = 12; public void testMethod() { int i = 0; i++; Console.WriteLine(i); } }
Deserialize to class with lock field and call testMethod:
class Program { static void Main(string[] args) { Settings set = null; using (FileStream fs = new FileStream(@"C:\test\tst.set", FileMode.Open, FileAccess.Read, FileShare.Read)) { BinaryFormatter bf = new BinaryFormatter(); set = (Settings)bf.Deserialize(fs); fs.Flush(); fs.Close(); } set.testMethod(); } } [Serializable] internal class Settings { private int _i = 12; private readonly object _lock = new object(); public void testMethod() { lock (_lock) { int i = 0; i++; Console.WriteLine(i); } } }
program will crash on testMethod call.
I didin't find anything related to this behavior in documentaion. I will check for null after deserialization and that will end my trouble.
Ok. How deserilization can assign null to my readonly field assigned on declaration?