How to implement one "catch'em all" exception handler with resume? - c#

I wonder how can I write a catch'em all exception handler in the application level which will give the user the option to resume the application flow?

If you are running a Windows Forms application: add a handler to the Application.ThreadException event.

I assume you are writing a Windows application in which case, yes, you can do this. I will leave the rights and wrongs of whether or not you should to others. There are already enough answers which look at this and I suggest you consider them carefully before you actually do this.
Note, that this code will behave differently in the debugger than it does if you run the application directly (another reason not to do it perhaps). To get the application to show the messagebox and to continue on thereafter you will need to run the application from explorer, not from visual studio.
Create a new Windows forms application. The code in Program.cs looks something like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Windows.Forms;
namespace WindowsFormsApplication2 {
static class Program {
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Form1 form1 = new Form1();
Application.ThreadException += new ThreadExceptionEventHandler(form1.UnhandledThreadExceptionHandler);
Application.Run(form1);
}
}
}
Then make the code in Form1 look something like this:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
namespace WindowsFormsApplication2 {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
public void UnhandledThreadExceptionHandler(object sender, ThreadExceptionEventArgs e) {
this.HandleUnhandledException(e.Exception);
}
public void HandleUnhandledException(Exception e) {
// do what you want here.
if (MessageBox.Show("An unexpected error has occurred. Continue?",
"My application", MessageBoxButtons.YesNo, MessageBoxIcon.Stop,
MessageBoxDefaultButton.Button2) == DialogResult.No) {
Application.Exit();
}
}
private void button1_Click(object sender, EventArgs e) {
throw new ApplicationException("Exception");
}
}
}
(Add button1 to the form and attach it button1_Click.)

It depends on what you mean by "resume". The trouble with exceptions is that unless you're very careful, by the time an exception happens your application state is quite possibly corrupt - you might have completed half an operation.
If you can isolate your operations - much like a database isolates transactions - then you can effectively let your user resume from the "last commit point". That will very much depend on the type of your application though. Could you give us more details about the kind of application you're building?

Use below code in your program.cs class. It will automatically Send mail when exception occurs.
using System;
using System.Windows.Forms;
using System.Net;
using System.Net.Mail;
using System.Threading;
namespace ExceptionHandlerTest
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.ThreadException +=
new ThreadExceptionEventHandler(Application_ThreadException);
// Your designer generated commands.
}
static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
{
var fromAddress = new MailAddress("your Gmail address", "Your name");
var toAddress = new MailAddress("email address where you want to receive reports", "Your name");
const string fromPassword = "your password";
const string subject = "exception report";
Exception exception = e.Exception;
string body = exception.Message + "\n" + exception.Data + "\n" + exception.StackTrace + "\n" + exception.Source;
var smtp = new SmtpClient
{
Host = "smtp.gmail.com",
Port = 587,
EnableSsl = true,
DeliveryMethod = SmtpDeliveryMethod.Network,
UseDefaultCredentials = false,
Credentials = new NetworkCredential(fromAddress.Address, fromPassword)
};
using (var message = new MailMessage(fromAddress, toAddress)
{
Subject = subject,
Body = body
})
{
//You can also use SendAsync method instead of Send so your application begin invoking instead of waiting for send mail to complete. SendAsync(MailMessage, Object) :- Sends the specified e-mail message to an SMTP server for delivery. This method does not block the calling thread and allows the caller to pass an object to the method that is invoked when the operation completes.
smtp.Send(message);
}
}
}
}

I don't think this is really feasible using a global error handler. You need to figure out what kind of errors are recoverable at different points in your application and write specific error handlers to address the errors as they occur -- unless you want to resort to application restart, which may or may not work depending on what the actual error is. In order to do any kind of resume, you'll need to save enough state to restart from a known good state.

You should read up on all the problems associated with VB's "On Error Resume Next" style of error handling. It sounds like you're trying to implement this for C#.
Even if you can resume from the point of where the exception is generated, this is a broken technique for error handling. There's no way for a global handler to actually be able to handle any error/exception - it can't possibly know what's required for any arbitrary situation.
You would have to set some sort of global variable, and have the mainline code continually check it for error indications (ie., use the VB technique).
I think the best you can do to recover from an error like you're describing is to catch the exception at the application level, log the problem, inform the user (and potentially generate/send some sort of problem report for you), and restart the application. Of course, if you catch the exception closer to the problem area, that handler has a chance to do something a bit more intelligent, so you should not rely on the app-level handler as a crutch - just as a fail-safe.

In some versions of .NET you can actually put a catcher around the Application.Run() (you'll find this in program.cs) and this should catch all the Main Thread's exceptions however in most cases this maybe poor design and wont give you much of an opportunity to "resume".
Additionally you will always have to manually handle any exceptions on background threads.
You can design an app to "catch all" and display a common error message and debug info, this is fine as long as you exit afterwards. What is highly discouraged is making a "resume" available to the user as this will probably give you more problems in the long-run.

This just screams bad design all over. Never use exceptions for things like this. Exceptions are ONLY to be used when something the programmer did not intend to occures.
If you want error-handling. dont use exceptions like this, rahter build a system where you save states and can go back to states etc... but using exceptions for state handling, bad idea.

Microsoft Enterprise Library Exception Handling Application Block has examples of how you can do this.
Basically you surround the code that can throw exceptions with this:
try
{
MyMethodThatMightThrow();
}
catch(Exception ex)
{
bool rethrow = ExceptionPolicy.HandleException(ex, "SomePolicy");
if (rethrow) throw;
}
Then you can configure the Policy to show a dialog to the user and ask if she wants to continue.
You still need to put try catch blocks around in your code at points where you believe you are at a consistent state.

Related

Not sure if I'm using "using" correctly c# in tftp app

I'm trying to use this pre-made C# tftp server app with my windows c# form. In the authors server example, which works great, he uses a console app. When I trying porting his console example into my form app it doesn't work (no errors, just doesn't connect) and I believe my issue is in the "using" statement:
using (var server = new TftpServer())
{
server.OnReadRequest += new TftpServerEventHandler(server_OnReadRequest);
server.OnWriteRequest += new TftpServerEventHandler(server_OnWriteRequest);
server.Start();
Console.Read();
}
Not sure if I understand correctly but I believe the Console.Read() blocks keeping the app from exiting. If this is the case how would I implement a equivalent with a form app. I just can't get my head around the "using". Sorry I'm new to c#.
Windows Forms will always remain open until they're explicitly closed by the user. They always have a thread reading the message queue for user input, so they won't exit the same way an unrestrained console application will. In Windows Forms, we have to worry a bit more about multithreading and concurrency than we would in console apps. It mostly comes naturally, but not always.
Because of that, you can't really use an equivalent to Console.Read() to hold off execution of the using disposal until the user requests it. If you did, your form would simply appear unresponsive.
However, you're in luck! A using block in C# is nothing more than syntactic sugar for remembering to call IDisposable.Dispose() after you're done with an object. So the equivalent to this in a Forms project could just be storing the server object in a class-wide field, then calling server.Dispose() on, say, a Button.Click event. That's, of course, just an example. You could also do it on Form.Closing if that felt more appropriate.
High-level, you want to do something like this:
Declare a field in your form class TftpServer server;.
Register a Load event and whatever you need for your server to function in your constructor.
Open your server field in the Form_Load event.
Use the server's events as you see so fit during the life of your Form. You may or may not have to worry about concurrency, but that's a matter for another question.
Call server.Dispose() in the form's Dispose event.
In essence,
class main : Form
{
private TftpServer server;
public main()
{
InitializeComponent();
this.Load += main_Load;
server = new TftpServer();
server.OnReadRequest += new TftpServerEventHandler(server_OnReadRequest);
server.OnWriteRequest += new TftpServerEventHandler(server_OnWriteRequest);
}
private void main_Load(object sender, EventArgs e)
{
server.Start();
}
private void server_OnReadRequest(/* I wasn't sure of the arguments here */)
{
// use the read request: give or fetch its data (depending on who defines "read")
}
private void server_OnWriteRequest(/* I wasn't sure of the arguments here */)
{
// use the write request: give or fetch its data (depending on who defines "write")
}
protected override void Dispose(bool disposing)
{
if (server != null) // since Dispose can be called multiple times
{
server.Dispose();
server = null;
}
}
}
The problem is that disposing the server is what is closing it. Keep in mind using is just syntactic sugar. The following two code chunks are [practically] equivalent:
var foo = new Foo();
try
{
foo.Do();
}
finally
{
foo.Dispose();
}
using (var foo = new Foo())
{
foo.Do();
}
You are fine blocking the main thread from exiting in a Console app, but in a Forms app it's different. The problem is not that you need to hold the thread inside the using by doing some sort of blocking operation. That would be bad, and the behavior would lock up your forms app. The problem is you don't want to use using. You want to new it up when you start the server, and then later on, on application exit, or on a stop click, explicitly dispose it with Dispose().
In a console application your TftpServer instance is listening until the thread exits which is only after a key is pressed which is detected by Console.Read()
In your forms app that Console.Read() isn't waiting around and so the using block finishes and that causes your server instance to fall out of scope.
So you are not exactly misusing the using but rather the intended use is not helping you at all. Take a look at using the task parallel library to let some background tasks run asynchronously.
A small note that also doubles as an answer, you could use a using block here, you just put it in your main function:
...(make your form and stuff)
using (var server = new TftpServer())
{
server.OnReadRequest += new TftpServerEventHandler(server_OnReadRequest);
server.OnWriteRequest += new TftpServerEventHandler(server_OnWriteRequest);
server.Start();
Application.Run(yourFormHere); //This blocks until the form is closed
}
Another option I forgot to mention is overriding Dispose in your Form. You probably want to do this. With this option you're guaranteed your server will be disposed (bar some event that would prevent it from being disposed either way [ie. being out of memory])

Why does Crossthreading work this way?

Solved
Seems that Oliver is right. After Several tries I got the exception and in debug mode i get it for sure. So this has to be all about timing. You should also check Matthew wattsons answer ;)
Example
First of all a little example that shall explain my confusion.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace testCrossThreading
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
new Thread(ThreadJob).Start();
}
void ThreadJob()
{
//label1.Text = "1";
changeText(label1, "1");
}
void changeText(Label L, String message)
{
L.Text = message;
}
}
}
Question
So now my question: if I uncomment label1.Text = "1"; in the function "ThreadJob" then I get an Cross thread exception as expected.
But if i leave it commented like the example shows it does work. But why?
The function is called by the sub thread and I don't invoke anything. So it is still the sub Thread and not the GUI thread that changes the text of label imo. Or am I missing something?
I would write it like this.
void ThreadJob()
{
Action a = () => label1.Text = "1";
this.Invoke(a);
}
I think it's just a timing issue. If you try to update a gui element from a non-gui thread the cross-thread exception can be thrown. You can even disable the whole cross-thread exceptions by calling
Form.CheckForIllegalCrossThreadCalls = false;
but after the exception is gone, the further behavior is undefined and can lead to very subtle bugs. So take the exception as a hint for a code smell but be aware that sometimes the exception won't be thrown even if it should be.
I think you may have a race condition, which is why results are varying.
If you attempt to change the Text property of a control which isn't currently displayed, then .Net doesn't care which thread changes it.
In your code, you start a thread from the constructor. The code which actually displays the form may or may not have displayed it before the code in the thread that sets the property executes.
When you call an extra function to set the property, the timings change and exposes the race condition.
You could test this by adding a Thread.Sleep(100) to the start of ThreadJob().

Is it Ok to put Application.Run() method in a catch to avoid application termination?

I am trying to keep the (beta version of my) application running as much as possible,So I placed another try-catch inside Program.cs as well in cases where some critical errors occur and shut the application down unexpectedly.And in the catch i rewrote the Application.Run() method so that the application can resume itself after being terminated for what ever reason.
Is it right to have such a plan for this specific scenario?
If it is not right,Then what else is recommended in order to keep the program running?
This is the sample code demonstrating what i mean:
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Hossein;
using Pishro.Classes;
namespace Pishro
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
try
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new frmMain());
}
catch(Exception exc)
{
API.SaveAndShowLog(exc);
Application.Run(new frmMain());
}
}
}
}
Globally handling exceptions is a good idea for logging and alerting.
An automatic restart policy like yours can be useful, yes. There is a risk however: If the crash has corrupted global data-structures restarting the app can have unpredictable results like silent data corruption. For example, files might still be open and locked. Locks might not have been released. Static variables might be in an undefined state. Rogue threads might still be running, unaware that the application UI was destroyed.
I recommend that you restart the app by starting a new process of your application. Let the old process die.
I think your question involves a deeper question.. Should I catch all the exceptions?
To keep going you could catch them all.. but all those possible exceptions that you don't expect or not know are probably bugs.
Maybe you should try to implement better error handling approach within your app. So all the exceptions are known or expected.
Instead of wrapping a try catch around your application run method, consider handling the exceptions with events.
static void Main()
{
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
MessageBox.Show("Exception handled");
}
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
}
Mainly the thread exception is the one you want but ideally - you would want to set up some form of logging/flagging the error to the user and still dispose of the program because it may cause the program to continue in an unfit state. Please put a button on your form and in the click event throw new Exception(""); and then the message box should display.

How to catch Unhandled Exception ? [duplicate]

I wonder how can I write a catch'em all exception handler in the application level which will give the user the option to resume the application flow?
If you are running a Windows Forms application: add a handler to the Application.ThreadException event.
I assume you are writing a Windows application in which case, yes, you can do this. I will leave the rights and wrongs of whether or not you should to others. There are already enough answers which look at this and I suggest you consider them carefully before you actually do this.
Note, that this code will behave differently in the debugger than it does if you run the application directly (another reason not to do it perhaps). To get the application to show the messagebox and to continue on thereafter you will need to run the application from explorer, not from visual studio.
Create a new Windows forms application. The code in Program.cs looks something like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Windows.Forms;
namespace WindowsFormsApplication2 {
static class Program {
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Form1 form1 = new Form1();
Application.ThreadException += new ThreadExceptionEventHandler(form1.UnhandledThreadExceptionHandler);
Application.Run(form1);
}
}
}
Then make the code in Form1 look something like this:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
namespace WindowsFormsApplication2 {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
public void UnhandledThreadExceptionHandler(object sender, ThreadExceptionEventArgs e) {
this.HandleUnhandledException(e.Exception);
}
public void HandleUnhandledException(Exception e) {
// do what you want here.
if (MessageBox.Show("An unexpected error has occurred. Continue?",
"My application", MessageBoxButtons.YesNo, MessageBoxIcon.Stop,
MessageBoxDefaultButton.Button2) == DialogResult.No) {
Application.Exit();
}
}
private void button1_Click(object sender, EventArgs e) {
throw new ApplicationException("Exception");
}
}
}
(Add button1 to the form and attach it button1_Click.)
It depends on what you mean by "resume". The trouble with exceptions is that unless you're very careful, by the time an exception happens your application state is quite possibly corrupt - you might have completed half an operation.
If you can isolate your operations - much like a database isolates transactions - then you can effectively let your user resume from the "last commit point". That will very much depend on the type of your application though. Could you give us more details about the kind of application you're building?
Use below code in your program.cs class. It will automatically Send mail when exception occurs.
using System;
using System.Windows.Forms;
using System.Net;
using System.Net.Mail;
using System.Threading;
namespace ExceptionHandlerTest
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.ThreadException +=
new ThreadExceptionEventHandler(Application_ThreadException);
// Your designer generated commands.
}
static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
{
var fromAddress = new MailAddress("your Gmail address", "Your name");
var toAddress = new MailAddress("email address where you want to receive reports", "Your name");
const string fromPassword = "your password";
const string subject = "exception report";
Exception exception = e.Exception;
string body = exception.Message + "\n" + exception.Data + "\n" + exception.StackTrace + "\n" + exception.Source;
var smtp = new SmtpClient
{
Host = "smtp.gmail.com",
Port = 587,
EnableSsl = true,
DeliveryMethod = SmtpDeliveryMethod.Network,
UseDefaultCredentials = false,
Credentials = new NetworkCredential(fromAddress.Address, fromPassword)
};
using (var message = new MailMessage(fromAddress, toAddress)
{
Subject = subject,
Body = body
})
{
//You can also use SendAsync method instead of Send so your application begin invoking instead of waiting for send mail to complete. SendAsync(MailMessage, Object) :- Sends the specified e-mail message to an SMTP server for delivery. This method does not block the calling thread and allows the caller to pass an object to the method that is invoked when the operation completes.
smtp.Send(message);
}
}
}
}
I don't think this is really feasible using a global error handler. You need to figure out what kind of errors are recoverable at different points in your application and write specific error handlers to address the errors as they occur -- unless you want to resort to application restart, which may or may not work depending on what the actual error is. In order to do any kind of resume, you'll need to save enough state to restart from a known good state.
You should read up on all the problems associated with VB's "On Error Resume Next" style of error handling. It sounds like you're trying to implement this for C#.
Even if you can resume from the point of where the exception is generated, this is a broken technique for error handling. There's no way for a global handler to actually be able to handle any error/exception - it can't possibly know what's required for any arbitrary situation.
You would have to set some sort of global variable, and have the mainline code continually check it for error indications (ie., use the VB technique).
I think the best you can do to recover from an error like you're describing is to catch the exception at the application level, log the problem, inform the user (and potentially generate/send some sort of problem report for you), and restart the application. Of course, if you catch the exception closer to the problem area, that handler has a chance to do something a bit more intelligent, so you should not rely on the app-level handler as a crutch - just as a fail-safe.
In some versions of .NET you can actually put a catcher around the Application.Run() (you'll find this in program.cs) and this should catch all the Main Thread's exceptions however in most cases this maybe poor design and wont give you much of an opportunity to "resume".
Additionally you will always have to manually handle any exceptions on background threads.
You can design an app to "catch all" and display a common error message and debug info, this is fine as long as you exit afterwards. What is highly discouraged is making a "resume" available to the user as this will probably give you more problems in the long-run.
This just screams bad design all over. Never use exceptions for things like this. Exceptions are ONLY to be used when something the programmer did not intend to occures.
If you want error-handling. dont use exceptions like this, rahter build a system where you save states and can go back to states etc... but using exceptions for state handling, bad idea.
Microsoft Enterprise Library Exception Handling Application Block has examples of how you can do this.
Basically you surround the code that can throw exceptions with this:
try
{
MyMethodThatMightThrow();
}
catch(Exception ex)
{
bool rethrow = ExceptionPolicy.HandleException(ex, "SomePolicy");
if (rethrow) throw;
}
Then you can configure the Policy to show a dialog to the user and ask if she wants to continue.
You still need to put try catch blocks around in your code at points where you believe you are at a consistent state.

How do i know if my windows service is working?

I have built a windows service to populate a database with my email inbox every 5 minutes.
I used a class inside my windows service the class gets my emails and writes them to my database, the class has been tested and works.
All i need the windows service to do is use a timer and call the class every 5 minutes, but i have no idea whats going on as i cant even test my windows service.
Please someone tel me what to do to test, if there is a way to test, or just blink luck and pray it works lol.
Also do u have to uninstall and re-install every time you want to test the service or is there an update service option? Please answer this i'm really interested even tho its not my main question.
This is my windows service, if u can point out any errors that would be amazing since i cant test for them. I think my timer might be wrong if some one could look at it?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Timers;
namespace EmailWindowsService
{
public partial class MyEmailService : ServiceBase
{
private Timer scheduleTimer1 = null;
private DateTime lastRun;
private bool flag;
public MyEmailService()
{
InitializeComponent();
if (!System.Diagnostics.EventLog.SourceExists("MySource"))
{
System.Diagnostics.EventLog.CreateEventSource(
"MySource", "MyNewLog");
}
eventLogEmail.Source = "MySource";
eventLogEmail.Log = "MyNewLog";
scheduleTimer1 = new Timer();
scheduleTimer1.Interval = 5 * 60 * 1000;
scheduleTimer1.Elapsed += new ElapsedEventHandler(scheduleTimer_Elapsed);
}
protected override void OnStart(string[] args)
{
flag = true;
lastRun = DateTime.Now;
scheduleTimer.Start();
eventLogEmail.WriteEntry("Started");
}
protected override void OnStop()
{
scheduleTimer.Stop();
eventLogEmail.WriteEntry("Stopped");
}
protected override void OnPause()
{
scheduleTimer.Stop();
eventLogEmail.WriteEntry("Paused");
}
protected override void OnContinue()
{
scheduleTimer.Start(); ;
eventLogEmail.WriteEntry("Continuing");
}
protected override void OnShutdown()
{
scheduleTimer.Stop();
eventLogEmail.WriteEntry("ShutDowned");
}
protected void scheduleTimer_Elapsed(object sender, ElapsedEventArgs e)
{
RetriveEmailClass Emails = new RetriveEmailClass();
if (flag == true)
{
eventLogEmail.WriteEntry("In getting Email Method");
Emails.ServiceEmailMethod();
lastRun = DateTime.Now;
flag = false;
}
else if (flag == false)
{
if (lastRun.Date < DateTime.Now.Date)
{
Emails.ServiceEmailMethod();
eventLogEmail.WriteEntry("In getting Email Method");
}
}
}
}
}
Surely you can test it. All you need is
start up the service
observe that it triggers the expected call after 5 minutes
(observe that it triggers the expected call every 5 minutes for a couple more times)
You can test this manually, or (preferably) create/use an automated test harness which allows you to test repeatedly and reliably, as many times as you want. This is possible even using a simple batch file.
To detect that the timer works correctly, you can inspect its log file. It also helps of course if you make the called class method configurable instead of hardcoding it. So you can run your automated tests using a dummy worker class which does not flood your inbox :-)
To make it even more testable, you can extract the timing logic from your service class too, so that it becomes runnable from a regular application. Then you can test it even easier, even using a unit test framework such as NUnit. This allows you to do more thorough testing, using different timing intervals etc. And the service class itself becomes an almost empty shell whose only job is to launch and call the other classes. If you have verified that all the classes containing real program logic (i.e. all the code which can fail) is unit tested and works fine, you can have much greater confidence in that your whole app, when integrated from its smaller parts, works correctly too.
Update
Looking through your code, it seems that you don't initialize flag anywhere, so its default value will be false. You should initialize it to true in the constructor, otherwise your email retriever won't ever get called even if the timer fires properly.
To set the interval to 1 minute, my first guess would be
scheduleTimer1.Interval = 1 * 60 * 1000;
James Michael Hare has on his blog written about a really nice template/framework he has made, making it lot easier to develop (and debug) Windows Services: C# Toolbox: A Debuggable, Self-Installing Windows Service Template (1 of 2)
It provides you with all the basics you need to quickly get started. And best of all, it give you a really nice way to debug your service as if it was a regular console application. I could also mention that it provides out of the box functionality to install (and uninstall) your service. Part two of the post can be found at this link.
I've used this myself a couple of times, and can really recommend it.
Refactor you logic in another class.
Write a simple console application invoking this class
Test it like a normal application.
Once it runs standalone, it should run as a service.
Beware on permissions and service registration, there are a couple of issues there (like having a sys user, or a desktop session).
A good practice is to use system logs (e.g. the ones you can inspect with eventvwr)
1.add this line to the place you want to break, then you can debug your service.
System.Diagnostics.Debugger.Break();
or
2.try to attach to your service progress from process explorer, then you can also debug your service.
or
3.use a log file to log what your service is doing.
You can attach a debugger to you running service instance from Visual Studio. Click "Debug" in the main menu, "Attach to Process...", select your service process from the list and click "Attach".
If you need to debug the startup of your service, you need to use System.Diagnostics.Debugger.Break().

Categories

Resources