For one thing, the actual code. Not being psychic, all I can tell you is
that you have an exception somewhere that has no handler. One common cause
of surprises is code that executes on a separate thread (either explicitly
or implicitly as a delegate called for asynchronous processing). Exceptions
do not propagate across threads -- if a thread has no top-level exception
handler, the exception goes unhandled.
There are two things you can do that will make your life a lot easier.
First, on service start, assign a handler to AppDomain.UnhandledException
event and have that log something more meaningful than the framework's
fall-back logging, which is nigh useless.
Second, modify your service so it can run as a regular console application,
so you can debug it. To do this, change the .Main() method to read something
like this:
if (Environment.UserInteractive) {
// Not a service
using (MyService s = new MyService()) {
s.OnStart();
Console.ReadLine();
s.OnStop();
}
} else {
// Service
ServiceBase.Run(new MyService());
}
Fair enough - here's the code:
The OnStart method:
protected override void OnStart(string[] args)
{
string szMsg;
FaxManagerServiceMain oFaxManagerServiceMain;
oFaxManagerServiceMain = new FaxManagerServiceMain();
Thread oThread = new Thread(new ThreadStart
(oFaxManagerServiceMain.Run));
oThread.Start();
szMsg = "The Fax Manager Service was started at " +
DateTime.Now.ToString();
System.Diagnostics.EventLog.WriteEntry(this.ServiceName, szMsg);
}
invokes the main Run method here:
public class FaxManagerServiceMain
{
public void Run()
{
FaxManager.FaxManager oFaxManager = new FaxManager.FaxManager
();
short sFrequencyInMinutes;
sFrequencyInMinutes = short.Parse
(ConfigurationSettings.AppSettings["MinutesBetweenFaxChecks"]);
while (true)
{
oFaxManager.GetFax();
//Get the settings from the app.config file
sFrequencyInMinutes = short.Parse
(ConfigurationSettings.AppSettings["MinutesBetweenFaxChecks"]);
//Once the faxes have been checked,
//sit tight until its time to check again
System.Threading.Thread.Sleep(sFrequencyInMinutes * 60 *
1000);
}
}
}
The oFaxManager.GetFax() method is in a DLL which performs a multi-
step process of obtaining faxes from a server. I have try...catch
blocks around all the main areas of the code so if an error occurs I
can write the information about it to the log and an emil will go to
me informing me of the problem. Here is a sample of one of the
try...catch blocks:
try
{
aFiles = Directory.GetFiles(szInboundDirectory, szFilePattern);
oTiffUtil = new InnovatixCommon.TiffUtil(@"c:\temp");
foreach (string szFullFileName in aFiles)
{
szFileName = szFullFileName.Substring
(szFullFileName.LastIndexOf("\\") + 1);
oTiffUtil.splitTiffPages(szFullFileName, szInboundDirectory);
if (System.IO.File.Exists(szInboundHistoryDirectory +
szFileName))
System.IO.File.Delete(szInboundHistoryDirectory +
szFileName);
System.IO.File.Move(szFullFileName, szInboundHistoryDirectory
+ szFileName);
Common.WriteLog(szLogFile, "Tif main file moved to " +
szInboundHistoryDirectory + szFileName);
}
}
catch (Exception ex)
{
string szError = "Error splitting Tif into separate pages: " +
ex.Message + " " + ex.InnerException.Message;
Common.WriteLog(szLogFile, szError);
SendEmail(szError);
return;
}
The problem is that when an error occurs it doesn't enter the catch
block. Though you say that errors don't propogate across thread, this
problem occurred within the existing thread. What gives?
I appreciate your help.
Thanks
Carl