1

I am Working with c# compact framework and vs2008. I am facing the issue on Lock statement. My application works most of the time but still hangs sometimes.

I tried these

1) Lock(this)
2) lock (Core.Processor.Input.GPSIDInput.gps)
3) Monitor.TryEnter(Core.Processor.Input.GPSIDInput.gps);
try{}
finally{ Monitor.Exit(this); }

Why is it not coming out when the lock fails as i am using "try catch block".

Gps.cs

[DllImport("coredll.dll")]
static extern int CloseHandle(IntPtr hObject);

public void Close()
{
    try
    {
        lock (Core.Processor.Input.GPSIDInput.gps)
        {

            if (newLocationHandle != IntPtr.Zero){
            CloseHandle(newLocationHandle);
            newLocationHandle = IntPtr.Zero;
            }......

        }
    }
    catch (Exception excpt)
    {
    //stack trace
    }
}

GPSIDInput.cs

namespace Core.Processor.Input
{
    public class GPSIDInput
    {
        .......
        public static Gps gps = new Gps();

        public static void CloseGPS()
        {
            gps.Close();
        }
    }
}
Sinatr
  • 20,892
  • 15
  • 90
  • 319
shiv
  • 127
  • 1
  • 3
  • 13
  • What do you mean by "when the lock fails" ? – Magnus Jan 27 '15 at 12:50
  • If a thread wants to acquire a lock and another thread has already got it then it will block, it does not throw an exception and carry on. Do you have multiple threads in your application? Are there other locks being acquired? It's possible you have a deadlock, but there's not enough info in your question. – Paolo Jan 27 '15 at 12:52
  • device hangs when it encounter lock. it is not able get inside lock. – shiv Jan 27 '15 at 12:53
  • Are you expecting this to work in multithreaded mode? – Amit Jan 27 '15 at 12:55
  • May be duplicate http://stackoverflow.com/questions/639493/in-c-sharp-how-can-i-safely-exit-a-lock-with-a-try-catch-block-inside – Devesh Jan 27 '15 at 12:55
  • @ paolo ya it is multi threaded, because of that i am trying to lock it. I want to release few handle which is in use. – shiv Jan 27 '15 at 12:58
  • You should only use a lock to proctect shared resources, data that may be used by two threads concurrently. In that case both threads need to use the same lock instance. Is your code making use of multiple threads that both need to access the same data? If not, you should not use locks at all. – R. Beiboer Jan 27 '15 at 13:00
  • where else do you use a lock with the same object? the code you posted should work as long as you not hold the lock to the same obejct in another thread the whole time – BoeseB Jan 27 '15 at 13:01
  • @ Boese no where i am using the lock. when ever the gps data resived the os keep on triggering application "newLocationHandle" i forcing it to close from application when not needed. os holds the handle to it – shiv Jan 27 '15 at 13:07
  • 1
    Then I think you should remove the lock from your code. When you have only one thread that can hold the lock, the lock is not needed. – R. Beiboer Jan 27 '15 at 13:12
  • Thank u all. Will try with all of ur inputs and will come back. – shiv Jan 28 '15 at 05:01

2 Answers2

5

Lock works like a critical section. Only one thread can 'hold the lock'. When one thread does, another thread that tries to hold the lock has to wait until the other thread releases it. There is no such thing as 'failing' the lock, it just waits for the thread that holds it, to release it.

R. Beiboer
  • 712
  • 9
  • 21
  • if in case it wait. it has come of it. why the device hang then. – shiv Jan 27 '15 at 13:01
  • when os trigger the event when new location received to the instansce.other wise it is used while lock – shiv Jan 27 '15 at 13:15
  • ya beiboer, if i remove lock most probably it won't hang. But it may interrupt by os and the user action may not take place that is why i am trying to lock it – shiv Jan 27 '15 at 13:25
  • If you mean that the Close() method may be called from multiple threads, then I think the answer of @BoeseB should solve the problem. When you use the `lock` statement, you should use an object instance, like in his answer. – R. Beiboer Jan 27 '15 at 13:32
3

Just a guess to solve the problem if you are only worried that two threads try to release the handle at the same time then use something like this:

object closeLockObj = new object();
public void Close()
{
    try
    {
        lock (closeLockObj)
        {

            if (newLocationHandle != IntPtr.Zero){
            CloseHandle(newLocationHandle);
            newLocationHandle = IntPtr.Zero;
            }......

        }
    }
    catch (Exception excpt)
    {
    //stack trace
    }
}

if other code aquires a lock on Core.Processor.Input.GPSIDInput.gps it could result in your application hanging. So its better to use a seperate lockObject

BoeseB
  • 695
  • 4
  • 17
  • When the OP means that the Close() method may be called from different threads simultaniously, this answer should fit. – R. Beiboer Jan 27 '15 at 13:28
  • Hello Boese & Beiboer. I tested device with the change it is working so for Thank u. 1) What is the reason for creating new object(closeLockObj), why are we trying to lock different object which is not relevant. 2) Lock Can be any dummy object or it should be an object of same class i am dealing. – shiv Jan 27 '15 at 16:11
  • 1
    look at the part about Deadlock for a short explanation why you should better use a object which is not exposed externally http://www.codeproject.com/Articles/37976/Writing-Thread-Safe-Code-in-C in your case some other code might have requested a lock on Core.Processor.Input.GPSIDInput.gps and so you Close Method couldnt get the lock and waited forever for the external code to release the lock. – BoeseB Jan 27 '15 at 19:43
  • 2
    You are not 'locking' that object, you use the object as a key for your lock. The compiler actually generates a call to Monitor.Enter using the object as the key. It is not as if the lock object itself is locked, or made read only, or whatever. The first thread to grab the lock will continue, the next threads that try to do that have to wait for the lock to be released. It is best practice to use a private object as the lock (key), because then you are sure you are the only one who will lock on this. – R. Beiboer Jan 27 '15 at 20:05