What is the right way to prevent re-placement and provide locking for certain operations?

I am developing a base class that, when inherited, will provide business functionality for context in a multi-threaded environment. Each instance can have lengthy initialization operations, so I want to make objects multiple. To do this, I need to be able to:

  • Assign a context to one of these objects so that it can do its job.
  • Prevent assignment of an object to a new context when it already has
  • Prevent access to specific members while the object has no context

In addition, each context object can be shared by many work objects.

Is there a correct synchronization primitive that matches what I'm trying to do? This is the sample I came 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 the properties and methods of the base class that should not be accessed, unless the object is in processing state.

 protected Context CurrentContext { get { this.ThrowIfNotProcessing(); return this.context; } } protected void SomeAction() { this.ThrowIfNotProcessing(); // do something important } 

At first, I wanted to use Monitor.Enter and related functions, but this does not interfere with reconnecting a single thread (several calls to BeginProcess in the original topic).

+6
source share
3 answers

There is one synchronization object in .NET that is not repetitive; you are looking for a semaphore.

Before doing this, make your ducks in a row and ask yourself how it might be possible that BeginProcess () can be called again in the same thread. This is very, very unusual, your code must be repeated for this. Usually this can only happen in a thread with a dispatcher pipeline, and a common GUI user interface thread is a common example. If this is really possible, and you really use Semaphore, then you will also face the consequences, your code will be inhibited. Since he switched to BeginProcess and kiosks on a semaphore. Thus, never terminate and never be able to call EndProcess (). There is a good reason why the monitor and mutexes are repetitive :)

+8
source

You can use the Semaphore class that comes with the .NET Framework 2.0.

A good use of Semaphores is to synchronize a limited amount of resources. In your case, it seems that you have resources, such as Context , that you want to share between consumers.

You can create a semaphore for managing resources such as:

 var resourceManager = new Semaphore(0, 10); 

And then wait for the resource to be available in the BeginProcess method using:

 resourceManager.WaitOne(); 

Finally, free the resource in the EndProcess method using:

 resourceManager.Release(); 

Here's a good blog about using Semaphores in a situation like yours:

http://www.dijksterhuis.org/using-semaphores-in-c/

+6
source

There is a very simple way to prevent reconnection (in a single thread):

 private bool bRefresh = false; private void Refresh() { if (bRefresh) return; bRefresh = true; try { // do something here } finally { bRefresh = false; } } 
-2
source

Source: https://habr.com/ru/post/954645/


All Articles