0

I have an enumeration that is shared between multiple threads:

public enum Action
{
   Read,
   Write,
   None
}

Within a class I have a variable of Action type:

public Action _action;

This is a shared variable, that is, it is updated and read from multiple threads.

For example, from one thread I do:

_action = Action.Read

And from another one:

if (_action == Action.Read)
{
}
else if (_action == Action.Write)
{
}
else if (_Action == Action.None)
{
}
else
{
}

So I would like to use Interlock to update and/or read it from different threads at the same time. How can I do it through a property?

I have seen many posts, for example below one:

How to apply InterLocked.Exchange for Enum Types in C#?

Problem here is that enumeration needs to cast to an int, but I would like to keep enumeration without casting. Is it possible? If so, could you post some example? Also Is it possible to combine volatile with interlock? I mean apply interlock on a volatile enumeration.

Willy
  • 9,848
  • 22
  • 141
  • 284
  • This and the linked question are asking the same thing: "I know how to solve this problem with casting. Can I solve it without casting?" I don't think saying "No, really, I don't want to use casting" invalidates those answers or makes this not a duplicate. You might try adapting some of the answers to the close-to-if-not-exactly-a-duplicate question [Interlocked.CompareExchange with enum](https://stackoverflow.com/q/18358518/150605), but I think you'll find that those solutions are no prettier/cleaner/more desirable than casting. Really. – Lance U. Matthews May 23 '17 at 00:04

1 Answers1

2

In this scenario Interlocked wouldn't be useful. Your series of if/then checks depend on the value of _action remaining unchanged as they all execute. Otherwise _action==Action.Read could be false, but before the next statement executes _action is set to Action.Read and all of the other conditions are false.

You'd want to use lock to ensure that nothing modifies _action while those statements are executing.

So you might have an object for your lock:

private readonly _lockObject = new object();

And then when _action is getting set:

lock(_lockObject)
{
    _action = newValue;
}

And when executing your conditions you could just read the value of _action within the lock and then release it. That way the lock is held for the shortest time possible. If _action gets modified while you're executing your conditions you won't be affected because you've created a separate value and you're no longer depending on the value of _action.

Action action;
lock(_lockObject)
{
    action = _action
}
if (action == Action.Read)
{
}
else if (action == Action.Write)
{
}
else if (action == Action.None)
{
}
else
{
}
Scott Hannen
  • 27,588
  • 3
  • 45
  • 62
  • And it is a good idea to make variable _action volatile as well in combination with lock? for example public volatile Action _action – Willy May 23 '17 at 07:42