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);
}
}
}
}