ExitTime not in Process ExitHandler

G

GrahamS

Hi,
I have a process being created by my own app. Both are console apps.

When I exit the app - I get an ExitHandler event as expected. In there - the
process says it has exited (HasExited=true;) BUT still the ExitTime is not
being set.

NB The process is being closed by pressing the 'Close Button' on the console
window.

All the docs say that if Hasexited is true - then ExitTime will be set - but
its not (sometimes) on my app :-((. Sometimes I get todays date - sometimes
1601...

Any reason for this please ???.

Thanks

Regards

Graham
 
G

GrahamS

Pete,

Thanks for the response - and you are right in that I would probably never
need this timestamp - but - it seems to me that if it should be being set -
then there is an underlying problem which is manifesting this way but may
have more side-effects on something else ;-). Best not to just ignore it in
my experience ;-).

I first noticed this NOT in the Exited event handler (as I only added this
later to check the problem), but in a background process which is monitoring
a number of processes it has created. If any has exited - it needs
restarting, so I was just going to log the 'event' and restart the process.

Incidentally I am this paranoid as I have another system (for which this
will become a replacement) with a simple GUI which crashes every now and then
with an OS-generated messagebox. It 'may' be down to thread interaction but
as it only happens at random after a few days - is VERY difficult to track
down - so I am re-architecting the whole solution to make it more robust :-O
- well its V1 code anyway ;-).

The ExitTime problem is highly reproducible in my code and I would be happy
to send that code on to Microsoft - if they ever read this and ask ;-)). It
does not always show 1601 - sometimes it shows the correct exit time.

All you have to do is create a console app, and in there launch a process
with another console app - put in a while(true) { sleep(100); } - then press
the close button to shut it down - or Ctrl-C etc. The outer app handles the
exited event so just show the time to the console. Do this a few times and
note the differences in exittime ;-)).

NB Running this on XP Pro SP3 - apps created in C# with VS2008 Sp1.

Maybe MS would like to comment.....

Regards

Graham

Peter Duniho said:
[...]
All the docs say that if Hasexited is true - then ExitTime will be set -
but
its not (sometimes) on my app :-((. Sometimes I get todays date -
sometimes
1601...

Sounds to me as though the ExitTime _is_ being set. After all, the docs
say that the property will throw an exception if the process hasn't exited.

Now, why the time might reflect an empty/zero DateTime value, I don't
know. I don't see anything in the docs for .NET or the unmanaged
reference for GetProcessTimes() (which I'd guess is what Process uses)
that would suggest you'd ever get anything except an actual time. I've
never needed the ExitTime information myself, and so I haven't noticed
this particular behavior in my own use of Process.

If you can show a concise-but-complete code example that reliably
demonstrates the problem, then it's possible someone can provide a more
detailed answer. Or maybe someone's run across the behavior themselves.

In the meantime, it seems to me that your Exited event handler is going to
be executed very close to the actual exit time, so for most purposes it
should suffice to just look at DateTime.Now in the event handler to get a
useful exit time, should you really need that information.

Pete
 
G

GrahamS

Pete,

Thanks for the response - and you are right in that I would probably never
need this timestamp - but - it seems to me that if it should be being set -
then there is an underlying problem which is manifesting this way but may
have more side-effects on something else ;-). Best not to just ignore it in
my experience ;-).

I first noticed this NOT in the Exited event handler (as I only added this
later to check the problem), but in a background process which is monitoring
a number of processes it has created. If any has exited - it needs
restarting, so I was just going to log the 'event' and restart the process.

Incidentally I am this paranoid as I have another system (for which this
will become a replacement) with a simple GUI which crashes every now and then
with an OS-generated messagebox. It 'may' be down to thread interaction but
as it only happens at random after a few days - is VERY difficult to track
down - so I am re-architecting the whole solution to make it more robust :-O
- well its V1 code anyway ;-).

The ExitTime problem is highly reproducible in my code and I would be happy
to send that code on to Microsoft - if they ever read this and ask ;-)). It
does not always show 1601 - sometimes it shows the correct exit time.

All you have to do is create a console app, and in there launch a process
with another console app - put in a while(true) { sleep(100); } - then press
the close button to shut it down - or Ctrl-C etc. The outer app handles the
exited event so just show the time to the console. Do this a few times and
note the differences in exittime ;-)).

NB Running this on XP Pro SP3 - apps created in C# with VS2008 Sp1.

Maybe MS would like to comment.....

Regards

Graham

Peter Duniho said:
[...]
All the docs say that if Hasexited is true - then ExitTime will be set -
but
its not (sometimes) on my app :-((. Sometimes I get todays date -
sometimes
1601...

Sounds to me as though the ExitTime _is_ being set. After all, the docs
say that the property will throw an exception if the process hasn't exited.

Now, why the time might reflect an empty/zero DateTime value, I don't
know. I don't see anything in the docs for .NET or the unmanaged
reference for GetProcessTimes() (which I'd guess is what Process uses)
that would suggest you'd ever get anything except an actual time. I've
never needed the ExitTime information myself, and so I haven't noticed
this particular behavior in my own use of Process.

If you can show a concise-but-complete code example that reliably
demonstrates the problem, then it's possible someone can provide a more
detailed answer. Or maybe someone's run across the behavior themselves.

In the meantime, it seems to me that your Exited event handler is going to
be executed very close to the actual exit time, so for most purposes it
should suffice to just look at DateTime.Now in the event handler to get a
useful exit time, should you really need that information.

Pete
 
G

GrahamS

Peter,

You are absolutely right - please accept my apologies ;-O. Many thanks for
your continued patience...

I glibly stated that this problem was a simple matter of two console apps,
and completely ignored that - at the time I was testing out a basic MSMQ
interface :-O. As the ExitCode and HasExited flag were being set - I rather
'assumed' that the ExitTime would be as well - and forgot that my second app
could have been doing anything else :-O

I modified your code to better fit the scenario I suggested (that of
pressing Ctrl-C in the second app). I also created it as two distinct console
apps and could not make the fault appear - as you rightly stated!.

I have however managed to reproduce the problem with a minimum of code BUT
it only happens (as far as my test goes) when I am running an MSMQ
'BeginReceive' thread in the controlled app!!. I have taken my code back to a
very basic app and show that below.

The app simply starts an MSMQ receiver in the second process and waits for
messages - there are none during this test - and the queue EXISTS and is
empty.

Pressing Ctrl-C (to simulate an unclean shutdown) in the second app makes
the first app display the exit time, randomly as '1601' or correct - on my
system.

I also take on-board your comments re MS and MSDN - but would suggest (to
MS) that they should at least be monitoring these newsgroups - as they claim
them to be 'Micorosoft Managed Newsgroups' :-O.

NB I was an MSDN subscriber for the past 15 years or so - but can no longer
afford it in the current economic climate :-O.

Code to reproduce the issue (maybe I should raise it as a bug - I don't know
:-O). I don't believe that me telling MS its actually a BUG is the right way
to go ;-O.

Anyway - don't want to prolong this thread and end up as a rant :-O - I
don't do those ;-)).

I am not 'expecting' you to try this out - as it may require installation of
MSMQ if you don't already use that !!

I know that pressing Ctrl-C is not a 'clean' shutdown - but thats the whole
point of the exercise - to simulate what might happen if the OS causes a
catastrophic failure. My final target for this code will be Windows CE - and
I have already has OS-generated crash messages appearing on that platform :-O.

Many thanks again for your help - it has forced me to identify the cause of
the error - even if I can't necessarily fix it :-O.

Code to simulate the error reported :

App 1 :
======
using System;
using System.Threading;
using System.Diagnostics;

namespace TestProcessExitTime
{
class Program
{
static void Main(string[] args)
{
while (true)
{
Thread.Sleep(100);
string procname = "TestProcessExitTime2.exe";
ProcessStartInfo info = new ProcessStartInfo(procname);
Process processChild = Process.Start(info);

while (true)
{
Thread.Sleep(100);
if (processChild.HasExited)
{
Console.WriteLine(string.Format("{0} has exited! at
{1} with {2:X}", procname, processChild.ExitTime, processChild.ExitCode));
break;
}
}
}
}
}
}

App 2: - (build as named app in App 1)
=====
using System.Messaging;

namespace TestProcessExitTime2
{
class Program
{
static void Main(string[] args)
{
using (MessageQueue queue = new
MessageQueue(".\\Private$\\Ems_UI"))
{
//create the receive handler to run asynchronously
queue.ReceiveCompleted += new
ReceiveCompletedEventHandler(queue_ReceiveCompleted);

//start message receiver
queue.BeginReceive();

//now we can just sit here and do housekeeping
while (true)
{
System.Threading.Thread.Sleep(100);
}
}
}
static void queue_ReceiveCompleted(object sender,
ReceiveCompletedEventArgs e)
{
MessageQueue myQ = sender as MessageQueue;
if (myQ != null)
{
System.Messaging.Message msg = myQ.EndReceive(e.AsyncResult);
}
}
}
}


Regards

Graham




Peter Duniho said:
[...]
The ExitTime problem is highly reproducible in my code and I would be
happy
to send that code on to Microsoft - if they ever read this and ask
;-)). It
does not always show 1601 - sometimes it shows the correct exit time.

Even Microsoft is unlikely to pursue the question unless you provide a
proper concise-but-complete code example that reliably demonstrates the
problem.
All you have to do is create a console app, and in there launch a process
with another console app - put in a while(true) { sleep(100); } - then
press
the close button to shut it down - or Ctrl-C etc. The outer app handles
the
exited event so just show the time to the console. Do this a few times
and
note the differences in exittime ;-)).

If it's that simple, why didn't you post a concise-but-complete code
example showing that? You can't possibly know for sure that the above
description is accurate unless you've created such an example, and if you
have created such an example, it's simple enough to copy and paste the
code, showing it here.

Now, I have in fact created just such an example (see below). I have run
it for five minutes (approximately 600 process executions) on three
different computers, and was unable to reproduce the problem you're
describing. So, obviously it's not actually as simple as you say.
NB Running this on XP Pro SP3 - apps created in C# with VS2008 Sp1.

I tested on:

-- XP Home, SP3
-- XP Pro, SP3
-- Windows 7 RC

Not reproducible on any of those systems with my own code.
Maybe MS would like to comment.....

If you want to report a bug, you need to use the Connect web site
(http://connect.microsoft.com/). This newsgroup is not monitored by
Microsoft, except for the purpose of replying to MSDN subscribers.

If the code I posted reproduces the problem on your computer, feel free to
use it in your bug report. Note, however, that the code alone will be
insufficient, because obviously it's not this code itself causing the
problem. You'll have to narrow the problem down to whatever
configuration-specific issue you've got on your computer causing the
problem.

Pete


using System;
using System.Threading;
using System.Diagnostics;

namespace TestProcessExitTime
{
class Program
{
static void Main(string[] args)
{
if (args.Length < 1)
{
bool fBadTime = false;
TimeSpan ts = new TimeSpan(0, 0, 1);

while (!fBadTime)
{
Process process = new Process();
ProcessStartInfo psi = new
ProcessStartInfo("TestProcessExitTime.exe", "dummy");

psi.WindowStyle = ProcessWindowStyle.Hidden;

process.Exited += (sender, e) =>
{
DateTime dt = DateTime.Now;

if ((process.ExitTime -
dt).Duration().CompareTo(ts) > 0)
{
fBadTime = true;
Console.Write("***** ");
}
Console.WriteLine(process.ExitTime.ToShortTimeString());
};

process.EnableRaisingEvents = true;
process.StartInfo = psi;
process.Start();
process.WaitForExit();
}

Console.WriteLine("press Enter to exit...");
Console.ReadLine();
}
else
{
Thread.Sleep(500);
}
}
}
}
 
G

GrahamS

Peter,

You are absolutely right - please accept my apologies ;-O. Many thanks for
your continued patience...

I glibly stated that this problem was a simple matter of two console apps,
and completely ignored that - at the time I was testing out a basic MSMQ
interface :-O. As the ExitCode and HasExited flag were being set - I rather
'assumed' that the ExitTime would be as well - and forgot that my second app
could have been doing anything else :-O

I modified your code to better fit the scenario I suggested (that of
pressing Ctrl-C in the second app). I also created it as two distinct console
apps and could not make the fault appear - as you rightly stated!.

I have however managed to reproduce the problem with a minimum of code BUT
it only happens (as far as my test goes) when I am running an MSMQ
'BeginReceive' thread in the controlled app!!. I have taken my code back to a
very basic app and show that below.

The app simply starts an MSMQ receiver in the second process and waits for
messages - there are none during this test - and the queue EXISTS and is
empty.

Pressing Ctrl-C (to simulate an unclean shutdown) in the second app makes
the first app display the exit time, randomly as '1601' or correct - on my
system.

I also take on-board your comments re MS and MSDN - but would suggest (to
MS) that they should at least be monitoring these newsgroups - as they claim
them to be 'Micorosoft Managed Newsgroups' :-O.

NB I was an MSDN subscriber for the past 15 years or so - but can no longer
afford it in the current economic climate :-O.

Code to reproduce the issue (maybe I should raise it as a bug - I don't know
:-O). I don't believe that me telling MS its actually a BUG is the right way
to go ;-O.

Anyway - don't want to prolong this thread and end up as a rant :-O - I
don't do those ;-)).

I am not 'expecting' you to try this out - as it may require installation of
MSMQ if you don't already use that !!

I know that pressing Ctrl-C is not a 'clean' shutdown - but thats the whole
point of the exercise - to simulate what might happen if the OS causes a
catastrophic failure. My final target for this code will be Windows CE - and
I have already has OS-generated crash messages appearing on that platform :-O.

Many thanks again for your help - it has forced me to identify the cause of
the error - even if I can't necessarily fix it :-O.

Code to simulate the error reported :

App 1 :
======
using System;
using System.Threading;
using System.Diagnostics;

namespace TestProcessExitTime
{
class Program
{
static void Main(string[] args)
{
while (true)
{
Thread.Sleep(100);
string procname = "TestProcessExitTime2.exe";
ProcessStartInfo info = new ProcessStartInfo(procname);
Process processChild = Process.Start(info);

while (true)
{
Thread.Sleep(100);
if (processChild.HasExited)
{
Console.WriteLine(string.Format("{0} has exited! at
{1} with {2:X}", procname, processChild.ExitTime, processChild.ExitCode));
break;
}
}
}
}
}
}

App 2: - (build as named app in App 1)
=====
using System.Messaging;

namespace TestProcessExitTime2
{
class Program
{
static void Main(string[] args)
{
using (MessageQueue queue = new
MessageQueue(".\\Private$\\Ems_UI"))
{
//create the receive handler to run asynchronously
queue.ReceiveCompleted += new
ReceiveCompletedEventHandler(queue_ReceiveCompleted);

//start message receiver
queue.BeginReceive();

//now we can just sit here and do housekeeping
while (true)
{
System.Threading.Thread.Sleep(100);
}
}
}
static void queue_ReceiveCompleted(object sender,
ReceiveCompletedEventArgs e)
{
MessageQueue myQ = sender as MessageQueue;
if (myQ != null)
{
System.Messaging.Message msg = myQ.EndReceive(e.AsyncResult);
}
}
}
}


Regards

Graham




Peter Duniho said:
[...]
The ExitTime problem is highly reproducible in my code and I would be
happy
to send that code on to Microsoft - if they ever read this and ask
;-)). It
does not always show 1601 - sometimes it shows the correct exit time.

Even Microsoft is unlikely to pursue the question unless you provide a
proper concise-but-complete code example that reliably demonstrates the
problem.
All you have to do is create a console app, and in there launch a process
with another console app - put in a while(true) { sleep(100); } - then
press
the close button to shut it down - or Ctrl-C etc. The outer app handles
the
exited event so just show the time to the console. Do this a few times
and
note the differences in exittime ;-)).

If it's that simple, why didn't you post a concise-but-complete code
example showing that? You can't possibly know for sure that the above
description is accurate unless you've created such an example, and if you
have created such an example, it's simple enough to copy and paste the
code, showing it here.

Now, I have in fact created just such an example (see below). I have run
it for five minutes (approximately 600 process executions) on three
different computers, and was unable to reproduce the problem you're
describing. So, obviously it's not actually as simple as you say.
NB Running this on XP Pro SP3 - apps created in C# with VS2008 Sp1.

I tested on:

-- XP Home, SP3
-- XP Pro, SP3
-- Windows 7 RC

Not reproducible on any of those systems with my own code.
Maybe MS would like to comment.....

If you want to report a bug, you need to use the Connect web site
(http://connect.microsoft.com/). This newsgroup is not monitored by
Microsoft, except for the purpose of replying to MSDN subscribers.

If the code I posted reproduces the problem on your computer, feel free to
use it in your bug report. Note, however, that the code alone will be
insufficient, because obviously it's not this code itself causing the
problem. You'll have to narrow the problem down to whatever
configuration-specific issue you've got on your computer causing the
problem.

Pete


using System;
using System.Threading;
using System.Diagnostics;

namespace TestProcessExitTime
{
class Program
{
static void Main(string[] args)
{
if (args.Length < 1)
{
bool fBadTime = false;
TimeSpan ts = new TimeSpan(0, 0, 1);

while (!fBadTime)
{
Process process = new Process();
ProcessStartInfo psi = new
ProcessStartInfo("TestProcessExitTime.exe", "dummy");

psi.WindowStyle = ProcessWindowStyle.Hidden;

process.Exited += (sender, e) =>
{
DateTime dt = DateTime.Now;

if ((process.ExitTime -
dt).Duration().CompareTo(ts) > 0)
{
fBadTime = true;
Console.Write("***** ");
}
Console.WriteLine(process.ExitTime.ToShortTimeString());
};

process.EnableRaisingEvents = true;
process.StartInfo = psi;
process.Start();
process.WaitForExit();
}

Console.WriteLine("press Enter to exit...");
Console.ReadLine();
}
else
{
Thread.Sleep(500);
}
}
}
}
 

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