Synchnroization with lock statement
-
A couple of days ago I asked here how to ensure that a generic list isn't modified while an operation like Find() or Exist() is performed on the list. I was recommended to use the lock-statement. Now I would like to know if it's enough to lock the list while adding or removing items from it? Or do I need to lock it while performing a non-changing operation like Find() on the list as well? Thanks for help!
-
A couple of days ago I asked here how to ensure that a generic list isn't modified while an operation like Find() or Exist() is performed on the list. I was recommended to use the lock-statement. Now I would like to know if it's enough to lock the list while adding or removing items from it? Or do I need to lock it while performing a non-changing operation like Find() on the list as well? Thanks for help!
Hi, you have to use the lock-statement while adding and removing and also for non-changing operations. The lock-statement is like a monitor (imagine a gatekeeper) that allows execution of a critical code block. So to be sure if you have several critical blocks that only one block is executed at one time you have to use the same gatekeeper for all blocks. Example:
// declare a lock-object (the gatekeeper) private Object thisLock = new Object(); public void AddItem(object item) { lock(thisLock) { // add to the list } } public object FindItem(object criteria) { lock(thisLock) { // search within the list } }
Be pay attention that all access to the list is within a lock-statement using the same object (gatekeeper). Hope this helps a bit. Regards SebastianIt's not a bug, it's a feature! Check out my CodeProject article Permission-by-aspect. Me in Softwareland.
-
Hi, you have to use the lock-statement while adding and removing and also for non-changing operations. The lock-statement is like a monitor (imagine a gatekeeper) that allows execution of a critical code block. So to be sure if you have several critical blocks that only one block is executed at one time you have to use the same gatekeeper for all blocks. Example:
// declare a lock-object (the gatekeeper) private Object thisLock = new Object(); public void AddItem(object item) { lock(thisLock) { // add to the list } } public object FindItem(object criteria) { lock(thisLock) { // search within the list } }
Be pay attention that all access to the list is within a lock-statement using the same object (gatekeeper). Hope this helps a bit. Regards SebastianIt's not a bug, it's a feature! Check out my CodeProject article Permission-by-aspect. Me in Softwareland.
Thanks for the reply! You're right. I did a test and tried it out. But is there some way around this? So while a non-changing operation is performed on the list other non-changing operations can get access to the list as well? So that only modifications to the list can be stopped while theese non-changing operations is happening to the list? The reason is I'm creating a WCF service and each client contacts the service on a different thread. Each time a clients calls a method on the service the list is searched. This means if several hundreds of clients are connected every thread is locking the list and it takes some time to search there will be a real performance decrease. A solution I guess is to wrap all non-changing operations in try-catch blocks and skip the lock but that seems like a real hack! EDIT: It's a static list we're talking about in this case. Thanks again!
-
Thanks for the reply! You're right. I did a test and tried it out. But is there some way around this? So while a non-changing operation is performed on the list other non-changing operations can get access to the list as well? So that only modifications to the list can be stopped while theese non-changing operations is happening to the list? The reason is I'm creating a WCF service and each client contacts the service on a different thread. Each time a clients calls a method on the service the list is searched. This means if several hundreds of clients are connected every thread is locking the list and it takes some time to search there will be a real performance decrease. A solution I guess is to wrap all non-changing operations in try-catch blocks and skip the lock but that seems like a real hack! EDIT: It's a static list we're talking about in this case. Thanks again!
Yup, this solution is a real hack. But the problem you refer to is the reader/writer problem. And guess what, the framework contains a solution for this called the ReaderWriterLock: http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlock.aspx[^] Didn't used it myself but it seems easy to utilize. It doesn't matter if it is a static list as long as you are using static methods to access the list (using a static monitor). EDIT: I have to correct myself: You don't need static methods. All you have to do is using a static monitor (gatekeeper). Regards Sebastian
It's not a bug, it's a feature! Check out my CodeProject article Permission-by-aspect. Me in Softwareland.
-
Yup, this solution is a real hack. But the problem you refer to is the reader/writer problem. And guess what, the framework contains a solution for this called the ReaderWriterLock: http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlock.aspx[^] Didn't used it myself but it seems easy to utilize. It doesn't matter if it is a static list as long as you are using static methods to access the list (using a static monitor). EDIT: I have to correct myself: You don't need static methods. All you have to do is using a static monitor (gatekeeper). Regards Sebastian
It's not a bug, it's a feature! Check out my CodeProject article Permission-by-aspect. Me in Softwareland.