The semaphore is initially closed because there are no free slots available. There must be some free before you are able to cross the WaitOne()
call.
sema = new Semaphore(0, 2);
This is allowing 0 enters, you need to modify 0 to the number of concurrent access you want to allow.