c# - Long-running access to a shared resource with the ability to release on request -


i'm not sure how best explain want, let me write illustrative code. basically: background thread loops through lots of work, on rare occasions needs interrupted.

// loop runs in long-running thread // lot of high-priority work on shared resource. // vast majority of time thread accessing resource. private void fastloop() {     lock (locker)     {         while (true)         {             dowork();              // somehow checking if thread needs shared resource.             // ideally i'd this,             // alas: monitor.blockedcount() doesn't exist.             while (monitor.blockedcount(locker) > 0)                 monitor.wait(locker);         }     } }  // methods called rarely, there many of them // code required lock , unlock secondary threads // should simple. private void otherthreads() {     lock (locker)     {         dosomethingelse();         monitor.pulse(locker);     } } 

the current implementation uses simplest approach, unlocking , locking again give other threads opportunity jump in.

private void fastloopcurrentimplementation() {     while (true)     {         lock (locker)             dowork();     } } private void otherthreadscurrentimplementation() {     lock (locker)         dosomethingelse(); } 

something tells me simplistic approach might have issues, though. if i'm not mistaken, loop can unlock , lock again though thread blocked. mean other methods may spend multiple main thread loop cycles blocked.

am right approach not ideal? preferred method of locking/unlocking?

you can count blocked threads own:

private long blockedcount = 0;  private void fastloop() {     lock (locker)     {         while (true)         {             dowork();              while (interlocked.read(ref blockedcount) > 0)                 monitor.wait(locker);         }     } }  private void otherthreads() {     try     {         var wasblocked = false;         if (!monitor.tryenter(locker))         {             wasblocked = true;             interlocked.increment(ref blockedcount);             monitor.enter(locker);         }          dosomethingelse();          if (wasblocked)             interlocked.decrement(ref blockedcount);          monitor.pulse(locker);     }         {         monitor.exit(locker);     } } 

Comments

Popular posts from this blog

python - Selenium remoteWebDriver (& SauceLabs) Firefox moseMoveTo action exception -

html - How to custom Bootstrap grid height? -

transpose - Maple isnt executing function but prints function term -