HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Synced/Atomic access

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
atomicaccesssynced

Problem

Forward

I would love any comments you have, any ideas, any flaws you can find, and any suggestions you might have regarding the code below.
If this is similar to other implementations, I would love to know about them, since this is something I came up with by myself, after not finding any solution 'out there', but I know there is nothing new here, just my way of doing things.

Also, this is my first time posting here, so please go easy on me if I did it wrong.

Description

Writing code for windows WinForms application, usually entails working asynchronously, and sometimes throwing some threads in the air, so that the UI will still be responsive, IO will happen in the background, data will stay fresh, and your users will love instead of hate you for the bugs you throw at them.

C# has the 'lock' keyword to help with creating Atomic operations, but what I find frustrating, is that most often then not, the data itself need to be guarded, but the sync syntax can be easily forgotten.

So I've created the following code for myself to manage object locking, via generics and extension methods, which allow me to easily wrap any data type I need to be kept safe, and use it only via the Synced context.

First the extension methods (or rather a single extension method with overloaded parameter signature to make it's use more natural) DoLocked.

DoLocked will perform a locked action, after verifying that the object is 'ready for work', with the option to 'wait' (or not) on the lock, will release the lock when the action has completed (or in case of an exception), and will let you know if the action was triggered or not.

So basically any object, for ex. ComplexClass complexObject, you want to performed an operation that is locked (with all the features mentioned above), the code will look something similar to:

complexObject.DoLocked(syncObj,
() => { if( isReady ) return true; },
true,
obj => {
    ...
    obj.Method();
    ...
    obj.Property = value;
    ...
};

Solution

While this may work in isolation, the problem here is that it only works if every caller uses your Synced class with the same syncObj as every other caller.

Also, the InnerObject exposes the actual class outside the synchronization wrapper so there is nothing which prevents someone modifying the instance separately.

A few other points around the actual "code style", you should alter your overloads for the DoLocked method, it's a good idea to add additional options after the common options. Since every method requires an action so that should be the first parameter, it helps keep the calling code consistent.

public bool DoLocked(Action action)
    public bool DoLocked(Action action, bool wait)
    public bool DoLocked(Action action, Func getIsReady)


If you are using .NET 4/4.5 you should use the System.Threading.SpinWait struct instead of the Thread.Sleep call, alternatively Thread.SpinWait is available in all versions of .NET.

Your parameters should be camel cased and not named after keywords - this T instance instead of this T This.

Code Snippets

public bool DoLocked(Action<T> action)
    public bool DoLocked(Action<T> action, bool wait)
    public bool DoLocked(Action<T> action, Func<bool> getIsReady)

Context

StackExchange Code Review Q#19178, answer score: 3

Revisions (0)

No revisions yet.