Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Release lock from another thread than the Monitor's owner

I have a critical section in code which is delimited by two function calls, say Start() and End(). They use a Monitor to block other threads during execution. Now my problem is, if some thread does't call End() for whatever reason, my whole process is in trouble, since every thread is waiting for this Monitor to get released.

Sure I could use TryEnter with timeout so that I won't wait forever, but this won't release the blocked Monitor, so my program will get into this timeout every time from this time on.

Is there a way to release a blocking Monitor from another thread if a given timeout is over?

void Start(){ Monitor.Enter(obj); }

void End(){ Monitor.Exit(obj); }

EDIT: We are calling Excel through com interop and we cannot be sure that the Excel process will always work as expected. Note this is a web application, so failing to deal for that case is deadly. Start() is called the first time, the request is calling an excel function, End() is called on Request end. There is always the possibility that excel process starts to hang.

EDIT2: I now hda the idea to store the owner of ent lock in a variable and on deadlock I could kill this thread. Wouldn't this release the lock?

                        if (Monitor.TryEnter(excelLocker, 10000) == false)
                        {
                            excelOwner.Abort();
                            excelOwner = null;
                        }
                        else
                        {
                            excelOwner = Thread.CurrentThread;
                        }
like image 279
codymanix Avatar asked Dec 29 '25 01:12

codymanix


1 Answers

The only thread that can release a lock is the thread that owns the lock. So no, you cannot directly "unblock" the monitor from another thread - this is not possible by design. If you were able to do this, other threads would be able to override the semantics of the lock by releasing it when they did not actually own it.

I am curious to know why you do not use a lock block so that Enter and Exit are guaranteed, instead of using a Monitor directly.

Update

After reading your comment I would highly recommend organizing your code so that you can localize your locking, rather than on request start and request end. If you use a lock you can still serialize access to Excel, but you can guarantee that Enter and Exit are called.

FYI a lock is a Monitor under the hood.

    lock(_syncObj)
    {
        //Do stuff
    }

    //Is equivalent to

    Monitor.Enter(_syncObj);
    try
    {
        //Do stuff
    }
    finally
    {
        Monitor.Exit(_syncObj);
    } 

Using a lock you could localize your locking of Excel as follows:

    //Client code
    ExcelUtil.DoStuff("bling")

    //...

    //Util class manages call to Excel and locking.
    public static class ExcelUtil
    {
        private static readonly object SyncObj = new object();

        public static void DoStuff(string someParam)
        {
            //Guaranteed locking and unlocking even if an exception occurs
            lock (SyncObj)
            {
                DoSomeStuffWithExcelFuncA();
                DoSomeStuffWithExcelFuncB();
            }
        }

        private static void DoSomeStuffWithExcelFuncA()
        {
            //...
        }

        private static void DoSomeStuffWithExcelFuncB()
        {
            //...
        }
    }

As an aside, why are you locking access to Excel? I am guessing that you are using Excel automation server-side for your ASP.Net application. Unless things have moved on significantly this was always very troublesome at least back a few years. If you take out a lock and Excel hangs, you are stuffed. There are 3rd party solutions that can be used instead of Excel automation. Perhaps newer versions of Excel like being used in this way?

Your pattern appears to serialize all requests so that only a single (Excel based) request can be executed at any one time - that doesn't seem to be very desirable.

like image 97
Tim Lloyd Avatar answered Dec 30 '25 17:12

Tim Lloyd



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!