I have a multi threaded application that writes to a settings xml file using a static method. I want to avoid that the file is being updated twice at the same time (causing accesss/write exception).
How do I do that?
This doesn't work:
namespace Program
{
public class Settings
{
private static void SetSettingsValue (string settings, string value)
{
// make this thread safe to avoid writing to a locked settings xml file
lock (typeof(Settings))
{
//write data to xml file
}
}
}
}
Static-locking, or a static-lock, was a type of locking mechanism. It was typically only used when transporting tibanna gas. It would seal the tibanna cylinders from the inside.
Locks In Synchronized Methods You might wonder what happens when a static synchronized method is invoked, since a static method is associated with a class, not an object. In this case, the thread acquires the intrinsic lock for the Class object associated with the class.
As a rule of thumb, you want the lock-object to have the same static -ness than the operated-on value. So if you manipulate non-static values only, you'll want a non-static lock object. If you manipulate static values only, you'll want a static lock object.
The lock statement acquires the mutual-exclusion lock for a given object, executes a statement block, and then releases the lock. While a lock is held, the thread that holds the lock can again acquire and release the lock. Any other thread is blocked from acquiring the lock and waits until the lock is released.
You should create a separate, static lock object and use that. DO NOT USE A STRING! Strings are automatically interned and there will be only one instance of each programmatically declared string so you can't guarantee exclusive access to the lock.
You should do this:
public class A {
private static Object LOCK = new Object();
private static void foo() {
lock(LOCK) {
// Do whatever
}
}
}
(The syntax may be incorrect; I'm a Java person mostly but the same rules about locking and String interning apply to C#)
The lock keyword enforces a mutual exclusion lock: only one thread can lock any particular object at a time. If a second thread calls foo
then it will block until the first thread has exited the lock block.
Take home messages: for a static method lock on a private static variable. Don't lock on Strings or typeof(...) because you cannot guarantee that no-one else is using that object. Always lock on an object you know is not touched by anyone else by making it private and making it new.
The concept of lock() is to use an existing-object it can reference and use to control whether access is granted.
static object SpinLock = new object();
lock(SpinLock)
{
//Statements
}
When the execution leaves the lock() block the reference is released and any other threads waiting to execute the code block can proceed (one at a time, of course).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With