Difference between SyncRoot property and Synchronized method?
-
Can anybody pleae explain me , if possible with exmamples, the different purposes of using SyncRoot property and Synchronized methods?
SyncRoot Property: Gets an object that can be used to synchronize access to the collection. public virtual object SyncRoot {get;} Property Value: An object that can be used to synchronize access to the collection. Synchronized Methods: Synchronisation plays an important role in multithreaded applications where the threads are not independent of each other and share common resources. This is because if two threads share common resources and try to manipulate the resources simultaneously, the resources become inconsistent. To tackle such situations synchronisation provides a lock on the resource that is shared among threads and makes a thread wait until the other thread finishes the job with the resource. Thus synchronisation ‘locks’ the shared resource and prevents another thread from using it. C# provides a lock keyword to lock the shared object or resource. Whatever is written inside the parenthesis following the lock keyword gets locked for the current thread and no other thread is permitted to obtain the lock on that resource or object. We can write an expression that evaluates to an object, or just the object on which we wish to have a lock, inside the parenthesis. Whatever the expression may be, the result should be a reference type. The code that uses the object to be synchronised should be written inside the block of the lock statement. To give you a more concrete example, consider two threads working on a file. If both the threads try to open the file and write to it simultaneously, an exception is thrown. Here what we need to do is synchronise both the threads in such a way that only one thread opens the file and writes in it at any given moment.
Regards, Satips.
-
SyncRoot Property: Gets an object that can be used to synchronize access to the collection. public virtual object SyncRoot {get;} Property Value: An object that can be used to synchronize access to the collection. Synchronized Methods: Synchronisation plays an important role in multithreaded applications where the threads are not independent of each other and share common resources. This is because if two threads share common resources and try to manipulate the resources simultaneously, the resources become inconsistent. To tackle such situations synchronisation provides a lock on the resource that is shared among threads and makes a thread wait until the other thread finishes the job with the resource. Thus synchronisation ‘locks’ the shared resource and prevents another thread from using it. C# provides a lock keyword to lock the shared object or resource. Whatever is written inside the parenthesis following the lock keyword gets locked for the current thread and no other thread is permitted to obtain the lock on that resource or object. We can write an expression that evaluates to an object, or just the object on which we wish to have a lock, inside the parenthesis. Whatever the expression may be, the result should be a reference type. The code that uses the object to be synchronised should be written inside the block of the lock statement. To give you a more concrete example, consider two threads working on a file. If both the threads try to open the file and write to it simultaneously, an exception is thrown. Here what we need to do is synchronise both the threads in such a way that only one thread opens the file and writes in it at any given moment.
Regards, Satips.
-
Now if the user supplies some number in the textbox and clicks on the purchase button, the following handler gets called: In this Sample Code FileInfo f; FileStream fs; byte total=100; f = new FileInfo ( “C:\\log.bin” ); Thread t = new Thread (new ThreadStart(checker)); t.IsBackground = true; t.Start();
private void purchase_Click ( object sender, System.EventArgs e ) { lock ( f ) { try { fs = f.OpenWrite( ) ; byte b = byte.Parse ( quantity.Text ) ; total = ( byte ) ( total - b ) ; fs.WriteByte ( total ) ; MessageBox.Show ( “Transaction Complete” + “\n” + “Item remaining: “ + total ) ; fs.Close( ) ; } catch { MessageBox.Show ( “Cannot Open file” ) ; } } }
Regards, Satips.
-
Can anybody pleae explain me , if possible with exmamples, the different purposes of using SyncRoot property and Synchronized methods?
Synchronized returns a collection that locks on each call, i.e. while you call a method or property, no other thread may modify the collection. This is convenient, but not enough. Imagine the following code snippet:
// remove head
if (myList.Count > 0)
myList.RemoveAt(0);In this case, you have two separate calls (querying "Count" and removing an object). However, between the calls, some other thread may access the list and e.g. clear it completely. In this case, RemoveAt will fail. For that scenario, you get the SyncRoot:
lock(myList.SyncRoot)
{
if (myList.Count > 0)
myList.RemoveAt(0);
}
We are a big screwed up dysfunctional psychotic happy family - some more screwed up, others more happy, but everybody's psychotic joint venture definition of CP
My first real C# project | Linkify!|FoldWithUs! | sighist -
Synchronized returns a collection that locks on each call, i.e. while you call a method or property, no other thread may modify the collection. This is convenient, but not enough. Imagine the following code snippet:
// remove head
if (myList.Count > 0)
myList.RemoveAt(0);In this case, you have two separate calls (querying "Count" and removing an object). However, between the calls, some other thread may access the list and e.g. clear it completely. In this case, RemoveAt will fail. For that scenario, you get the SyncRoot:
lock(myList.SyncRoot)
{
if (myList.Count > 0)
myList.RemoveAt(0);
}
We are a big screwed up dysfunctional psychotic happy family - some more screwed up, others more happy, but everybody's psychotic joint venture definition of CP
My first real C# project | Linkify!|FoldWithUs! | sighist -
Thanks Peter, But still i am not clear. First point is, if we synchronize the whole method, how other thread can make calls between Count and RemoveAt? Secondly, instead of lock(mylist.syncRoot) can't we specify lock(mylist)?
kumar.bs wrote:
if we synchronize the whole method, how other thread can make calls between Count and RemoveAt?
They can't (as long as they use the lock), and that's the whole point. because between "Count" and "RemoveAt" noone may modify the list. Keep in mind that querying Count is usually very fast, so lock acquisition and RemoveAt will take the majority of execution time anyway.
kumar.bs wrote:
lock(mylist.syncRoot) can't we specify lock(mylist)?
Two problems: First, "List Proxies". The synchronization works correct only if all threads accessing the list use the same object to lock on. However, the List interface might not hold the data itself, but expose the interface for some underlying data. If one thread lokcs on the list proxy, and another thread locks on the underlying data, we have the concurrent access we need to avoid. Second, Lock Order. There is a problem wiht locking on publicly visible symbols. When you have two locking objects A and B, one thread might lock in the order A, B the other in order B,A. This leads to a deadlock situation that cannot be solved. That's why locking on public objects is almost always a bad idea. You need to be very clear which lock objects exsit in your code (and the code you call!), and give them a definite order. SyncRoot helps here a little bit since it is a dedicated object used for locking, that is provided by the underlying data. helped? :)
We are a big screwed up dysfunctional psychotic happy family - some more screwed up, others more happy, but everybody's psychotic joint venture definition of CP
My first real C# project | Linkify!|FoldWithUs! | sighist -
kumar.bs wrote:
if we synchronize the whole method, how other thread can make calls between Count and RemoveAt?
They can't (as long as they use the lock), and that's the whole point. because between "Count" and "RemoveAt" noone may modify the list. Keep in mind that querying Count is usually very fast, so lock acquisition and RemoveAt will take the majority of execution time anyway.
kumar.bs wrote:
lock(mylist.syncRoot) can't we specify lock(mylist)?
Two problems: First, "List Proxies". The synchronization works correct only if all threads accessing the list use the same object to lock on. However, the List interface might not hold the data itself, but expose the interface for some underlying data. If one thread lokcs on the list proxy, and another thread locks on the underlying data, we have the concurrent access we need to avoid. Second, Lock Order. There is a problem wiht locking on publicly visible symbols. When you have two locking objects A and B, one thread might lock in the order A, B the other in order B,A. This leads to a deadlock situation that cannot be solved. That's why locking on public objects is almost always a bad idea. You need to be very clear which lock objects exsit in your code (and the code you call!), and give them a definite order. SyncRoot helps here a little bit since it is a dedicated object used for locking, that is provided by the underlying data. helped? :)
We are a big screwed up dysfunctional psychotic happy family - some more screwed up, others more happy, but everybody's psychotic joint venture definition of CP
My first real C# project | Linkify!|FoldWithUs! | sighist