0
votes

I am currently having trouble with a System.Threading.Timer when deploying my Windows Service to a Win2k3 Server. It works just fine ticking every second (overkill for debugging purposes) on my local machine when I install it, but after I install it to the server, the service starts successfully then never fires the timer event once. Has anyone run into a situation similar to this before? Most of my research has turned up issues that were apparently prevalent in .NET 1.1 from forever ago. Thanks for your time and help.

   protected override void OnStart(string[] args)
   {
        int interval = Int32.Parse(ConfigurationManager.AppSettings["SleepTime"]) * 1000;
        TimerCallback cb = new TimerCallback(ProcessTimerEvent);
        QueueWorker worker = new QueueWorker();
        workTimer = new Timer(cb, worker, interval, 1000);

    }
    private static void ProcessTimerEvent(object obj)
    {
        if (obj is QueueWorker)
        {
            QueueWorker qw = (QueueWorker)obj;
            qw.doWork();
        }
    }
    class QueueWorker
    {
        public void doWork()
        {
           // work happening here
        }
    }

UPDATE:

I've found that it has something to do with the user that the service needs to run as. When the service runs as System, the threads work great. Anyone know what permissions are needed for a user to be able to run the threads? I've tried using the "Act as part of the operating system" in the local security settings, but that just causes the service to start up then immediately fail when logged in as the user I added.

3
Really obvious question: what is the app.Config value for SleepTime on the server? Other option: use System.Timers.Timer instead.ligos
I had a System.Timers.Timer before I implemented it this way. I got the same behavior on my server, service would start then the timer event would never fire. Then I read that Win 2k3 server does some funny threading stuff and that Timer may not work how I would expect. The SleepTime value right now is 1 second for my testing purposes. Later it will be whatever I need it to be when I'm not testing.mtgibbs21
Can you post the links regarding w2k3's behaviour? Can you build a console test app to rule out win service stuff? That would also be much easier to test with Console.WriteLine. And, sorry to ask stupid questions, SleepTime is 1000 milliseconds = 1 second, right?ligos
I could probably build a console test app, but I believe the issue with Win2k3 server was the fact that threading in services was the problem to begin with. And yeah, 1000 ms = 1 s.mtgibbs21

3 Answers

1
votes

The timer might be firing. You can run DebugView on the target machine:

http://technet.microsoft.com/en-us/sysinternals/bb896647.aspx

Then you can put calls in your code to see what is executing like this:

System.Diagnostics.Debug.WriteLine("Beginning of Timer event...");

System.Diagnostics.Debug.WriteLine("End of Timer event");
0
votes

A couple of solutions I can suggest:

  1. Use a console app and not a windows service. Run your console app from the task scheduler.
  2. Build your own timer class. Use your own thread(s) and sleep for your poll interval. On wake, do your work. Then sleep again.

And for completeness, here are some of the articles which detail the actual bug:

0
votes

Alright. Thanks for all your suggestions on this. I made a very aggressive log scheme and I believe that the server was killing my threads for some reason. I added a GC.KeepAlive(workTimer) and it seems to have resolved the issue of the timer not ticking.

Just in case someone else runs into this problem, it appears to me that the Local System gets thread priority, but other users can potentially have their threads destroyed for some reason or the other. Since I don't have complete access to the server that I am deploying this on, I will chalk the fix up to the KeepAlive or the server team fixed something behind my back.