A cleaner alternative might look like the following. You do not need a semaphore to get the calling thread to wait until the lock is acquired. Notice how I have used a ManualResetEvent and made a redundant lock construct for that purpose.
Once the outer lock is acquired the event is signalled and since locks are reentrant the inner lock will be acquired immediately. Now, I have used a semaphore to throttle the execution of AsyncToSearchPage.
Up vote 1 down vote favorite share g+ share fb share tw.
I'm developing a thread safe class and I want to wrap async method call around a sync method call. Maybe I'm not looking for a definition of "asynccall" method, but something close to it. When calling AsyncToStartSearchPage() on the instance, I want the calling thread to block until the new thread obtains the lock on the object.
That's where the semaphore comes in. The asyncCalls lock is to restrict the use. Maybe it isn't the best implementation, but I feel it needs some way of restricting the number of async requests at a time.
Any feed back would be great. The application use is that I have a consumer/producer model where a thread calling this method would begin the ToStartPage() method call and place it into the buffer. On the other side I want a thread to take the object with no possibilty of changing the state of the object before ToStartPage() has finished.
Before this, I had issues where the consumer would obtain lock on the object before the spun of thread was able to obtain lock and perform the ToStartPage(). Private readonly Object obj_Lock = new Object(); private readonly Object asyncCalls = new Object(); private Semaphore asyncSema = new Semaphore(0, 1); //sync method call which has a async calling wrapper public void ToSearchPage() { lock (obj_Lock) { //do something } } //public async method wrapper public bool AsyncToStartSearchPage() { //used to limit one async call. //not crazy about this part, but I feel it needs something like this if (Monitor.
TryEnter(asyncCalls, 1)) { try { Thread t = new Thread(asyncToStartPage); t.Start(); // blocks until the new thread obtains lock on object asyncSema.WaitOne(); } finally { Monitor. Exit(asyncCalls); } return true; } else { return false; } } private void asyncToStartPage() { lock (obj_Lock) { // now that I have aquired lock, release calling thread asyncSema.Release(); ToSearchPage(); } } c# .net multithreading asynchronous link|improve this question edited Sep 23 '09 at 16:53 asked Sep 23 '09 at 16:44Kevin9218 43% accept rate.
– Henk Holterman Sep 23 '09 at 17:13 A: Will this model work. B: Any suggestions for a better implementation. – Kevin Sep 23 '09 at 17:20 You want to throttle async calls, but you want to block the calling thread during this throttling process?
You might want to ask a different question detailing your requirements and ask for suggestions. – Will? Sep 23 '09 at 17:28 1 Will this work?
Maybe. I'd hate to make a guess about whether some piece of multithreaded code will work without thoroughly testing it. – Will?
Sep 23 '09 at 17:32 Thread A will be calling AsyncToStartSearchPage() on obj prior to placing into a blocking buffer, where Thread B will be waiting to take obj out of buffer with the assumption the obj is in a state left by the operation ToSearchPage(). I don't want either A or B to be waiting on the ToSearchPage() call, so I'd like it to be async to reduce this chance. The call can take several seconds.
Need more detail? – Kevin Sep 23 '09 at 20:31.
A cleaner alternative might look like the following. You do not need a semaphore to get the calling thread to wait until the lock is acquired. Notice how I have used a ManualResetEvent and made a redundant lock construct for that purpose.
Once the outer lock is acquired the event is signalled and since locks are reentrant the inner lock will be acquired immediately. Now, I have used a semaphore to throttle the execution of AsyncToSearchPage. Public class YourThreadSafeClass { private Object m_Lock = new Object(); private Semaphore m_Semaphore = new Semaphore(1, 1); public void ToSearchPage() { lock (m_Lock) { // Actual work goes here.
} } public bool AsyncToSearchPage() { // Throttle access using a semaphore if (m_Semaphore. WaitOne(0)) { try { ManualResetEvent e = new ManualResetEvent(false); Thread t = new Thread( () => { // Acquire the lock here for the purpose of signalling the event lock (m_Lock) { e.Set(); ToSearchPage(); // The lock will be acquired again here...thats ok } } ); t.Start(); e.WaitOne(); // Wait for the lock to be acquired return true; } finally { // Allow another thread to execute this method m_semaphore.Release(); } } return false; } } Keep in mind that this a slightly cleaner way of doing the same general thing. However, I recommend avoiding this approach altogether as it is still ugly.
I am not really understanding the need to throttle access to the asynchronous method nor have it block until the wrapped synchronous method acquires its lock anyway. Instead, consider the BeginXXX/EndXXX asynchronous pattern that is used throughout the . NET Framework.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.