user3026017
user3026017

Reputation: 919

Disposing a manualResetevent on another thread

Similar to this question I have a class with a private ManualReset event:

class A {
       private ManualResetEvent mre = new ManualResetEvent(true);
       private void Method(){
            //do something
            mre.Reset();
       }      
       public bool WaitForItem(int timeout){
           try{
               return mre.WaitOne(timeout)
           }catch(ObjectDisposedException){
               return false;
           }
      }
      public void Dispose(){
           mre.Dispose();
      }
}

How can I check that when Dispose is called WaitForItem method returns false, and doesn't block waiting.

The code is something similar to:

   A a = new A(1);
   a.Method();
   bool finished = true;
   Thread t1 = new Thread(() =>
   {
       finished = a.WaitForItem(Timeout.Infinite);
   });
   Thread t2 = new Thread(() =>
   {
       a.Dispose();
   });
   t1.Start();
   t2.Start();
   t1.Join();
   t2.Join();

The code blocks in waiting an item forever (at t1.Join()). I understood that calling Close, which is also a mean of disposing an object, doesn't affect the state of the handle, but how can I exit the method with false (catching an ObjectDisposedException) ?

Even though instead of calling a.Dispose() on the second thread calling another method which Disposes the ManualResetEvent the call to WaitOne() it's blocked.

Upvotes: 0

Views: 910

Answers (1)

MKR
MKR

Reputation: 20095

The ObjectDisposedException is raised only when an object is already disposed before calling a member function. This is not happening in your case as function mre.WaitOne(timeout) is called before mre.Dispose().

Once simple fix could be to call mre.WaitOne(timeout) function in a loop with a shorter timeout value. e.g. one want to have 10 seconds timeout for WaitForItem function then mre.WaitOne(timeout) can be called with just 1 sec timeout and it will give up after 10 tries.

A typical implementation could for WaitForItem function is explained below. WaitForItem has got 3 possible return values.

1 = Set is triggered on mre 0 = Set is not triggered within specified timeout -1 = Object is dispose before timeout.

public int WaitForItem(int timeout){
   try{
       int nReturnCode = 0;
       int nTimeElapsed = 0;
       while (true)
       {
           if (mre.WaitOne(1000))  //just wait for  1 second
           {
               nReturnCode = 1; //Set call on ManualResetEvent
               break;
           }
           else  //Timeout need to repeat
           {
               nTimeElapsed += 1000;
               if (nTimeElapsed > timeout)
               {
                   nReturnCode = 0; //timeout
                   break;
               }
           }
       }
       return nReturnCode;
   }catch(ObjectDisposedException){
       return -1; //Exception 
   }

}

Upvotes: 1

Related Questions