2

So I have a simple test using Monitor.Wait with a timeout set for three seconds. It's my understanding that, when the time expires, a virtual pulse is sent to the monitor to release the wait. In my test, however, that never seems to happen. Can someone explain what's going on. Here's my test code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace BlockingMethodFoo
{
    class Program
    {
        static void Main(string[] args)
        {
            WaitFoo foo = new WaitFoo();

            foo.StartMethod();

            Console.WriteLine("Done. Press enter");
            Console.ReadLine();

        }
    }

    public class WaitFoo
    {
        private object _waitObj = new object();
        private string _message = string.Empty;

        public void StartMethod()
        {
            Thread waitThread = new Thread(new ThreadStart(new Action(() => { WaitMethod(); })));

            _message = string.Empty;

            Console.WriteLine("Starting wait");

            _message = "Time Out";

            lock (_waitObj)
            {
                waitThread.Start();

                Monitor.Wait(_waitObj, TimeSpan.FromSeconds(3));
            }

            Console.WriteLine(_message);

        }

        private void WaitMethod()
        {

            lock (_waitObj)
            {
                _message = Console.ReadLine();
                Monitor.Pulse(_waitObj);
            }

        }
    }
}
Deduplicator
  • 44,692
  • 7
  • 66
  • 118
Hexum064
  • 349
  • 2
  • 14
  • 1
    The timeout doesn't do what you hope it does. Monitor.Wait() cannot return until it can re-acquire the lock. That cannot possibly happen until you press Enter so the WaitThread() method releases the lock. The timeout argument is only effective if the other thread doesn't call Pulse(). – Hans Passant May 19 '14 at 00:49

1 Answers1

1

Monitor.Wait will return false if the timeout expires and it couldn't get the lock.

http://msdn.microsoft.com/en-us/library/tdc87f8y.aspx

You have to check the return of Monitor.Wait and for example throw a TimeOutException if you see fit.

SharpC
  • 6,974
  • 4
  • 45
  • 40
vtortola
  • 34,709
  • 29
  • 161
  • 263
  • Hi vtortola. I've read that link a few times now and it seems to imply that, yes, Monitor.Wait will indeed return false if the timeout expires before it could get a lock but the problem, as Hans states, is that the Wait does not return just because the timeout expires. – Hexum064 May 19 '14 at 17:40
  • I see. I saw the code and that detail caught my attention. I am glad you found your solution. – vtortola May 20 '14 at 11:16