Reputation: 1477
I have a service that creates a thread with a loop that should run until the mutex is signalled by another process. I have the following in my service code
private readonly Mutex _applicationRunning = new Mutex(false, @"Global\HsteMaintenanceRunning");
protected override void OnStart(string[] args)
{
new Thread(x => StartRunningThread()).Start();
}
internal void StartRunningThread()
{
while (_applicationRunning.WaitOne(1000))
{
FileTidyUp.DeleteExpiredFile();
_applicationRunning.ReleaseMutex();
Thread.Sleep(1000);
}
}
Now I have a console application that should claim the mutex and force the while loop to be exited
var applicationRunning = Mutex.OpenExisting(@"Global\HsteMaintenanceRunning");
if (applicationRunning.WaitOne(15000))
{
Console.Write("Stopping");
applicationRunning.ReleaseMutex();
Thread.Sleep(10000);
}
When the console application tries to open the mutex I get the error "The wait completed due to an abandoned mutex." Whats wrong here?
Upvotes: 1
Views: 749
Reputation: 3821
I recommend that you use the Service's built-in stop signal rather than a mutex. The mutex class is more appropriate for managing exclusive access to a shared resource, which is not what's going on here. You could also use a system event but since services already have a built-in mechanism for signaling when they're stopping, why not use it?
Your service's code would look like this:
bool _stopping = false;
Thread _backgroundThread;
protected override void OnStart(string[] args)
{
_backgroundThread = new Thread(x => StartRunningThread());
_backgroundThread.Start();
}
protected override void OnStop()
{
_stopping = true;
_backgroundThread.Join(); // wait for background thread to exit
}
internal void StartRunningThread()
{
while (!stopping)
{
FileTidyUp.DeleteExpiredFile();
Thread.Sleep(1000);
}
}
Then, your console application would need to use the framework's ServiceController class to send the shut down message to your service:
using System.ServiceProcess;
...
using (var controller = new ServiceController("myservicename")) {
controller.Stop();
controller.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(15.0));
}
Upvotes: 1