MrProgram
MrProgram

Reputation: 5242

C# windows service can't stop

I'm getting "The service cannot accept control messages at this time" when trying to stop the service. I don't really understand why this is happening. Can someone help me with this? I thought my lock would prevent this.

The Patrol method takes about ~30-40 sec to run.

private static readonly string ConnectionString = ConfigurationManager.AppSettings["ConnectionString"];
private static readonly int runMinInterval = Convert.ToInt32(ConfigurationManager.AppSettings["RunMinInterval"]);
private Object myLock = new Object();
private Timer timer;

public DealWatchdogService()
{
    InitializeComponent();
}

protected override void OnStart(string[] args)
{
    Watchdog.Patrol(ConnectionString, new DealWatchdogService());
    timer = new Timer();
    timer.Enabled = true;
    timer.Interval = 60000 * runMinInterval;
    timer.AutoReset = false;
    timer.Start();
    timer.Elapsed += timer_Elapsed;
}

protected override void OnStop()
{
    lock (myLock)
    {
        timer.Stop();
        timer = null;
        base.OnStop();
    }
}

private void timer_Elapsed(object sender, ElapsedEventArgs e)
{
    lock (myLock)
    {
         if (timer == null)
                return;
         Watchdog.Patrol(tycheConnection, new DealWatchdogService());
         timer.Start();
    }
}

EDIT: Maybe some help but the service stops fine sometimes, but when it has been up and running for a week or so I get that error.

Upvotes: 2

Views: 2390

Answers (1)

Scott Chamberlain
Scott Chamberlain

Reputation: 127543

The Patrol method takes about ~30-40 sec to run.

I think the problem may be OnStart() is taking too long because of Patrol's length to finish and is setting a flag stating the system is locked up. Put your startup code on to a background thread so OnStart can finish more quickly.

protected override void OnStart(string[] args)
{
    //This line does not block.
    Task.Run(() => RealStart());
}

private void RealStart()
{
    Watchdog.Patrol(ConnectionString, new DealWatchdogService());
    timer = new Timer();
    //timer.Enabled = true; //Calling .Start() has the same effect.
    timer.Interval = 60000 * runMinInterval;
    timer.AutoReset = false;
    timer.Elapsed += timer_Elapsed;
    timer.Start(); //Start should be called after you have set .Elapsed
}

The only other thing it could be is something is going wrong inside timer_Elapsed but you never showed us what that code is doing.

Upvotes: 1

Related Questions