Prev: Multiple Concurrent TCP/IP Clients
Next: Exception handling in unManaged code when being called from managed code
From: Michal on 27 Apr 2010 05:25 Hi, maybe it's a simple problem for most of you, but I can't find an easy way to quite simple problem, let me describe: Let's have this code: public ClassToChange() { ... //some other methods internal List<AnyDataClass> LockAndGetData() { Monitor.Enter(cs); return data; } internal Unlock() { Monitor.Exit(cs); } private object cs = new object(); private List<AnyDataClass> data = new List<AnyDataClass>(); } public class Editor { public Editor(ClassToChange editedObject) { this.editedObject = editedObject; } public void MyFunctionToChangeData() { List<AnyDataClass> data = editedObject.LockAndGetData(); ... // change data editedObject.Unlock(); } private ClassToChange editedObject; } class Program { static void Main() { Editor ed = new Editor(new ClassToChange()); ed.MyFunctionToChangeData(); } } So my aim is to let Editor change the data of ClassToChange in a thread-safe way. But as you can see to call all the List data = editedObject.LockAndGetData(), then not to forget the editedObject.Unlock() is very boring to write (and not so safe). Do you have any easy solution for this? Only solution I have, there might be the CS as attribute of ClassToChange and use lock {} in Editor, but I would need an attribute to every data object of ClassToChange, who would check if the cs is locked to make it safe. So that's also not a good way. Any ideas?
From: Peter Duniho on 27 Apr 2010 06:00 Michal wrote: > [...] > So my aim is to let Editor change the data of ClassToChange in a thread-safe > way. But as you can see to call all the List data = > editedObject.LockAndGetData(), then not to forget the editedObject.Unlock() > is very boring to write (and not so safe). Do you have any easy solution for > this? > > Only solution I have, there might be the CS as attribute of ClassToChange > and use lock {} in Editor, but I would need an attribute to every data object > of ClassToChange, who would check if the cs is locked to make it safe. So > that's also not a good way. > > Any ideas? If the synchronization needs to happen at the level of operations within the Editor class, then your synchronization object should also be in the Editor class. Of course, this means that the Editor class has to be the de facto owner of your ClassToChange instance, and no other code should be modifying the ClassToChange instance while the Editor class is manipulating it. But that's just good program design anyway. It should not be a problem to require that. In some cases, it may be feasible to simply make the ClassToChange class the thread-safe one. In that case, rather than having the Editor class try to lock and unlock, just do the synchronization in the ClassToChange class for each operation that might modify the class's contents. This would lead to more locking and unlocking, but coherency of the data would still be preserved. Finally, if you decide that neither of the above can possibly work (and I would recommend strongly that you not come to that conclusion…in particular, in your example it really looks like the synchronization should be handled entirely by the Editor class, with the ClassToChange class being left not thread safe), you could implement a "do work" interface in your ClassToChange class, so that the Editor class simply passes a delegate that is invoked while the lock is held. For example: class ClassToChange { void DoSynchronizedWork(Action action) { lock (cs) { action(); } } private readonly object cs = new object(); } class Editor { public void MyFunctionToChangeData() { editedObject.DoSynchronizedWork(MyFunctionToChangeDataImpl); } private void MyFunctionToChangeDataImpl() { // change data } private ClassToChange editedObject; } Hope that helps. Pete
From: Patrice on 27 Apr 2010 06:02 Hello, > So my aim is to let Editor change the data of ClassToChange in a > thread-safe > way. But as you can see to call all the List data = > editedObject.LockAndGetData(), then not to forget the > editedObject.Unlock() > is very boring to write (and not so safe). Do you have any easy solution > for > this? Try the SyncLock statement that is intended to simplify Enter/Exit calls. The doc is at : http://msdn.microsoft.com/en-us/library/3a86s51t(VS.80).aspx -- Patrice
From: Peter Duniho on 27 Apr 2010 06:14 Patrice wrote: > Try the SyncLock statement that is intended to simplify Enter/Exit calls. > The doc is at : > > http://msdn.microsoft.com/en-us/library/3a86s51t(VS.80).aspx This is the C# newsgroup. The equivalent is the "lock" statement. Neither VB.NET's "SyncLock" nor C#'s "lock" offer the semantics that the OP is asking for (i.e. retaining the lock across method calls). Granted, as I suggested in my reply to the OP, the semantics being asked for should be avoided. :) Nevertheless, I don't think that suggesting "lock" (or "SyncLock", were this a VB.NET newsgroup) would in and of itself suffice to answer the question. Pete
From: Patrice on 27 Apr 2010 07:00 > This is the C# newsgroup. The equivalent is the "lock" statement. Neither > VB.NET's "SyncLock" nor C#'s "lock" offer the semantics that the OP is > asking for (i.e. retaining the lock across method calls). Good point. Sometimes I just mix groups. IMO retaining the lock was not the OP intent and was more caused by the implementation attempt... -- Patrice
|
Next
|
Last
Pages: 1 2 3 Prev: Multiple Concurrent TCP/IP Clients Next: Exception handling in unManaged code when being called from managed code |