Execute actions from a queue in a thread safe manner. More...
Public Member Functions | |
ActionQueue () | |
Construct the ActionQueue. Do this on whatever thread you want your actions to be executed on. More... | |
void | Update () |
Execute any actions in the queue. More... | |
void | Enqueue (Action action) |
Add an action to the queue. More... | |
Action | CreateActionWrapper (Action action) |
Get a thread-safe version of an Action. More... | |
Action< T1 > | CreateActionWrapper< T1 > (Action< T1 > action) |
CreateActionWrapper(Action) More... | |
Action< T1, T2 > | CreateActionWrapper< T1, T2 > (Action< T1, T2 > action) |
CreateActionWrapper(Action) More... | |
Action< T1, T2, T3 > | CreateActionWrapper< T1, T2, T3 > (Action< T1, T2, T3 > action) |
CreateActionWrapper(Action) More... | |
Action< T1, T2, T3, T4 > | CreateActionWrapper< T1, T2, T3, T4 > (Action< T1, T2, T3, T4 > action) |
CreateActionWrapper(Action) More... | |
void | Validate (Type type) |
Only allow ValueTypes and thread safe types to be passed as arguments to wrapped Actions More... | |
void | CheckIfOwnerThread () |
Throw an exception if not on the right thread More... | |
Execute actions from a queue in a thread safe manner.
Actions can be added to the queue from any thread and will be executed on the owner thread. The owner thread is the thread that instantiates the ActionQueue The owner thread is responsible for calling Update() periodically.
To use, call CreateActionWrapper() and pass in your Action to get back a new Action that you can use in place of the original Action. You can execute this new Action on any thread and it will automatically queue itself to be executed on the owner thread instead.
The CreateActionWrapper() method makes some effort to ensure thread safety by only allowing ValueTypes and Messages as arguments.
NobleConnect.ActionQueue.ActionQueue | ( | ) |
Construct the ActionQueue. Do this on whatever thread you want your actions to be executed on.
void NobleConnect.ActionQueue.CheckIfOwnerThread | ( | ) |
Throw an exception if not on the right thread
Action NobleConnect.ActionQueue.CreateActionWrapper | ( | Action | action | ) |
Get a thread-safe version of an Action.
When the wrapper Action is executed on whatever thread, it adds the wrapped Action to the thread-safe queue so that it can be executed on the owner thread. Actions that take arguments require an extra layer of wrapping since our Queue only holds parameterless Actions. The solution is to use some clever scoping to pass the parameters from the wrapper Action through a parameterless action that gets added to the queue. When the queued action is executed it calls the wrapped Action and passes in the arguments from the outer wrapper.
action |
Action<T1> NobleConnect.ActionQueue.CreateActionWrapper< T1 > | ( | Action< T1 > | action | ) |
Action<T1, T2> NobleConnect.ActionQueue.CreateActionWrapper< T1, T2 > | ( | Action< T1, T2 > | action | ) |
Action<T1, T2, T3> NobleConnect.ActionQueue.CreateActionWrapper< T1, T2, T3 > | ( | Action< T1, T2, T3 > | action | ) |
Action<T1, T2, T3, T4> NobleConnect.ActionQueue.CreateActionWrapper< T1, T2, T3, T4 > | ( | Action< T1, T2, T3, T4 > | action | ) |
void NobleConnect.ActionQueue.Enqueue | ( | Action | action | ) |
Add an action to the queue.
This method is called from within the wrapper when a wrapped action is executed on whatever thread. The wrapped action is then queued to be executed on the owner thread. You can also call it manually to add any paremeterless action to the queue directly. This is thread-safe when called from within a wrapper or from the owner thread. This is NOT thread-safe if called directly outside of the owner thread, so use with caution and be aware that anything the Action touches will be from the owner thread and not the thread that created the Action. In general that either means you must create a copy for anything accessed from within the Action or access only immutable types. If you absolutely must access something mutable from within an Action added on not-the-owner thread, then you should make sure to never mutate the mutable thing after Enqueuing the action because to do so would not be thread safe.
action |
void NobleConnect.ActionQueue.Update | ( | ) |
Execute any actions in the queue.
We lock on actions since it is a shared resource between the threads. Each action is removed from the Queue as it is executed so the queue will always be empty after this method has executed.
void NobleConnect.ActionQueue.Validate | ( | Type | type | ) |
Only allow ValueTypes and thread safe types to be passed as arguments to wrapped Actions
Value types are thread safe because they are copied. Message, CandidatePair, and Message Transactions have also been carefully designed to be thread safe.
type |