0

I have a lock to synchronize access to Bluetooth resources which I am using in 10 different places and I want to keep track of when was the last time this lock was acquired without adding a piece of code to all the 10 places where it's being used.

Consider

private DateTime lastTimeLockAcquired;
private static object _lock = new Object()

Which is being used in different places like

public SendData1(){
   lock(_lock){
        // Do work
   }

public sendData2(){
   lock(_lock){
       // Do work 
   } 

My initial idea was to create functions like

private void GetLock(){
    Monitor.Enter(_lock);
    lastTimeLockAcquired = DateTime.Now;
}
private void ReleaseLock(){
    Monitor.Exit(_lock);
}

But I would prefer to create a class and move the whole lock and DateTime object to a separate place and access the lock from there if there is any clean way to do that.

Jai dewani
  • 143
  • 1
  • 9
  • 2
    Create a class that implements IDisposable. Do the lock creation in the constructor of that class and the Release in Dispose along the measuring code for the aquiring time. Then you can use a somewhat standard using syntax. `using(new MyLovelyLock()) { /*do work*/ }` – Ralf Jul 11 '23 at 16:57
  • Out of curiosity, how is the *"last time this lock was acquired"* information useful? How are you planning to use this information? Btw be aware that casually reading the `lastTimeLockAcquired` without using the `_lock` could result in a [torn read](https://stackoverflow.com/questions/9008454/simulate-tearing-a-double-in-c-sharp "Simulate tearing a double in C#") on 32 bit machines. – Theodor Zoulias Jul 11 '23 at 23:00
  • @TheodorZoulias there is a shared resource that goes to sleep if no request is sent to it for 10-15 seconds. I want to run a timer thread that will check ever 1-2 seconds if the difference between the current time and the last time this resource was used is more than 10 seconds, send a request to keep the resource awake – Jai dewani Jul 12 '23 at 04:33
  • 1
    Ah, I see. Personally I would do it differently. I would instantiate a [`System.Threading.Timer`](https://learn.microsoft.com/en-us/dotnet/api/system.threading.timer), and I would call `.Change(15000, 15000)` after each `SendData1`/`SendData2` operation. This way a request will be sent after 15 sec of inactivity. The `Change` method is thread-safe. – Theodor Zoulias Jul 12 '23 at 04:46
  • 1
    Thanks @TheodorZoulias. I am personally using System.Timers.Timer so I looked up the equivalent of Change() and the best answer I could find was to call `Stop()` and `Start()` on [this question](https://stackoverflow.com/questions/1042312/how-to-reset-a-timer-in-c). WIll be club this a `Restart()` method and will use this as for now – Jai dewani Jul 12 '23 at 06:25
  • 1
    Personally I am not a fan of the `System.Timers.Timer` component. It's not a well designed component IMHO. You can read my arguments at the bottom of [this](https://stackoverflow.com/questions/70947206/how-to-create-a-thread-with-await-methods-inside/70950102#70950102 "How to create a thread with await methods inside?") answer. – Theodor Zoulias Jul 12 '23 at 06:40

0 Answers0