I'm designing a base class that, when inherited, will provide business functionality against a context in a multithreaded environment. Each instance may have long-running initialization operations, so I want to make the objects reusable. In order to do so, I need to be able to:
- Assign a context to one of these objects to allow it to do its work
- Prevent an object from being assigned a new context while it already has one
- Prevent certain members from being accessed while the object doesn't have a context
Also, each context object can be shared by many worker objects.
Is there a correct synchronization primitive that fits what I'm trying to do? This is the pattern I've come up with that best fits what I need:
private Context currentContext;
internal void BeginProcess(Context currentContext)
{
// attempt to acquire a lock; throw if the lock is already acquired,
// otherwise store the current context in the instance field
}
internal void EndProcess()
{
// release the lock and set the instance field to null
}
private void ThrowIfNotProcessing()
{
// throw if this method is called while there is no lock acquired
}
Using the above, I can protect base class properties and methods that shouldn't be accessed unless the object is currently in the processing state.
protected Context CurrentContext
{
get
{
this.ThrowIfNotProcessing();
return this.context;
}
}
protected void SomeAction()
{
this.ThrowIfNotProcessing();
// do something important
}
My initial though was to use Monitor.Enter
and related functions, but that doesn't prevent same-thread reentrancy (multiple calls to BeginProcess
on the original thread).
throw if the lock is already acquired
and don't want to wait for current processing to finish: Why not justthrow if current context is not null
? – Stoned