ManualResetEvent.WaitOne Method hangs, even though called with a timeout value

F

firstname

Hi,

The below code hangs even though I have provided 30 second timeout for
WaitOne. The myFun() is called by multiple threads almost at the same time.
Is there something wrong with the below code or is this a known issue?

myFun()
{
m_evConnectToDB.Reset(); // defined as : ManualResetEvent
m_evConnectToDB = new ManualResetEvent(false);
Thread thDatabase = new Thread(new ThreadStart(ConnectToDB));
thDatabase.Name = "MyThread";

thDatabase.Start();

m_evConnectToDB.WaitOne(new TimeSpan(0, 0, 30), true); //<---this 30
second timeout is never fired and application hangs here
if (thDatabase.IsAlive)
{
thDatabase.Abort();
}
}

Thanks
Su
 
F

firstname

Hello,

Shouldn't the WaitOne() with a timeout return, irrespective what my
application does or the thread I spwan, is there any exceptions for this
expected behaviour ?.
The issue is not reproducable at our lab, but this is intermittantly
happenning at a customer site. I grabed a hangdump and the call stack for
myFun() that calls WaitOne with timeout look like this:

////
Operating System Windows Server 2003 Service Pack 2
Number Of Processors 4
Process ID 3428
Process Image C:\Program Files\myserviceExe.exe
System Up-Time 5 day(s) 19:44:29
Process Up-Time 5 day(s) 19:30:11
Thread 32 - System ID 3704
Entry point mscorwks!Thread::intermediateThreadProc
Create time 04/03/09 12:30:03 AM
Time spent in user mode 0 Days 00:00:00.531
Time spent in kernel mode 0 Days 00:00:00.046


This thread is not fully resolved and may or may not be a problem. Further
analysis of these threads may be required.

Function Source
ntdll!KiFastSystemCallRet
ntdll!NtDelayExecution+c
kernel32!SleepEx+68
mscorwks!EESleepEx+bb
mscorwks!CExecutionEngine::ClrSleepEx+e
mscorwks!ClrSleepEx+14
mscorwks!Thread::UserSleep+63
mscorwks!ThreadNative::Sleep+ce
<Unloaded_I.DLL>+60f8abf
mscorlib_ni+216d66
mscorlib_ni+2201ef
mscorlib_ni+216ce4
mscorwks!CallDescrWorker+33
mscorwks!CallDescrWorkerWithHandler+a3
mscorwks!MethodDesc::CallDescr+19c
mscorwks!MethodDesc::CallTargetWorker+1f
mscorwks!MethodDescCallSite::CallWithValueTypes+1a
mscorwks!ThreadNative::KickOffThread_Worker+192
mscorwks!Thread::DoADCallBack+32a
mscorwks!Thread::ShouldChangeAbortToUnload+e3
mscorwks!Thread::ShouldChangeAbortToUnload+30a
mscorwks!Thread::ShouldChangeAbortToUnload+33e
mscorwks!ManagedThreadBase::KickOff+13
mscorwks!ThreadNative::KickOffThread+269
mscorwks!Thread::intermediateThreadProc+49
kernel32!BaseThreadStart+34

///////


Thank you
Su


Peter Duniho said:
Hi,

The below code hangs even though I have provided 30 second timeout for
WaitOne.

The "below code" isn't a concise-but-complete code sample that reliably
demonstrates the problem. So, by itself, it doesn't do anything, never
mind hangs.
The myFun() is called by multiple threads almost at the same time.
Is there something wrong with the below code or is this a known issue?

There's definitely something wrong with the code you posted: you are
calling Thread.Abort() as a way of managing your thread lifetime.

But, there's nothing obvious in the code you posted that would explain why
the call to WaitOne() never times out. You will need to post a
concise-but-complete code sample that reliably demonstrates the problem
for anyone to comment on that.

See below for a concise-but-complete code sample that demonstrates that
WaitHandle.WaitOne() does in fact work as advertised.

Pete


using System;
using System.Threading;

namespace TestWaitHandleTimeout
{
class Program
{
static void Main(string[] args)
{
ManualResetEvent mre = new ManualResetEvent(false);

new Thread(delegate()
{
while (!mre.WaitOne(0))
{
Thread.Sleep(1000);
Console.WriteLine(DateTime.Now);
}
}).Start();

mre.WaitOne(new TimeSpan(0, 0, 30), true);

mre.Set();

Console.WriteLine("done");
Console.ReadLine();
}
}
}
 
B

Ben Voigt [C++ MVP]

firstname said:
Hi,

The below code hangs even though I have provided 30 second timeout for
WaitOne. The myFun() is called by multiple threads almost at the same
time. Is there something wrong with the below code or is this a known
issue?

myFun()
{
m_evConnectToDB.Reset(); // defined as : ManualResetEvent
m_evConnectToDB = new ManualResetEvent(false);
Thread thDatabase = new Thread(new ThreadStart(ConnectToDB));
thDatabase.Name = "MyThread";

thDatabase.Start();

I would tend to think that this line (the call to Start) is hanging, not the
WaitOne. The return address on the stack is the next line, not the call
that's currently in progress.
 
F

firstname

Hello,

From the hang dump I can see the ConnectToDB thread has actually started,
But with you observation in mind when relooked at the code , I could see the
"ConnectToDB()" method is not defined as Static method. So I am wondering
how did this got compiled at the first place, also the '"ConnectToDB" method
is accessing few non static member variables.
Also the spawned "ConnectToDB" thread is hanging for sure inside oracle
library, this is the reason there is the timeout and abort logic placed
inside the code.

Thank you
Su
 
B

Ben Voigt [C++ MVP]

Are all threads running at default priority? Your watcher thread really
should be given a higher priority than the worker thread it is keeping an
eye on.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top