Windows Service with Publish/Subscribe Pattern

C

cmgarcia17

I have two windows services that I've written: the first is a "Listener
Service" that listens for MSMQ Message delivery. The second is a
"Watcher Service" that monitors the state of the first. If the
"Listener Service" goes down I want the "Watcher Service" to receive a
notification and perform a set action.

To enable this communication I've written a separate assembly (that
both services reference) that exposes two interfaces :
IServiceStatePublisher and IServiceStateSubscriber. The way that I
register the "Watcher Service" as a subscriber to the "Listener
Service" is with the following code in the OnStart event of the
"Watcher Service"::

protected override void OnStart(string[] args)
{
//Line 1
ServiceBase qw = new QueueWatcher();
//Line 2
((IServiceStatePublisher)fd).addSubscriber((IServiceStateSubscriber)this);
//Line 3
ServiceBase.Run(qw);
}

I thought it reasonable that this would work, however, when I start the
"Watcher Service" the Application Event log shows the message "Service
cannot be started. An instance of the service is already running". I've
determined that the error is specific to the code at Line 3, but I
can't identify the reason it's happening. Neither service is running
when the "Watcher Service" is started and I don't have the ability to
step into the ServiceBase code to see what's going on there.

I'm stumped, so any help is greatly appreciated.
 
M

Michael Bray

(e-mail address removed) wrote in
I have two windows services that I've written: the first is a
"Listener Service" that listens for MSMQ Message delivery. The second
is a "Watcher Service" that monitors the state of the first. If the
"Listener Service" goes down I want the "Watcher Service" to receive a
notification and perform a set action.

Perhaps a better route would be to completely decouple the two services,
and write a separate (new) 'watcher' service that utilizes the
ServiceController class to monitor the status of the Listener service, and
restart it if necessary.

-mdb
 
G

Guest

cmgarcia,
You can use this pattern to debug a windows service without it being
installed. It should be self-explanatory:

// The main entry point for the process
static void Main()
{
#if (!DEBUG)
System.ServiceProcess.ServiceBase[] ServicesToRun;
ServicesToRun = new System.ServiceProcess.ServiceBase[] { new Service1() };
System.ServiceProcess.ServiceBase.Run(ServicesToRun);
#else
// debug code: allows the process to run as a non-service
// will kick off the service start point, but never kill it
// shut down the debugger to exit
Service1 service = new Service1();
service.();
System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);
#endif
}

========================================
Possibly the problem you describe is caused by forgetting to make both the
service and the installer classes all have distinct, separate service names?
Peter
 
C

Christian Garcia

If I do that I lose the notification event model that the design
pattern gives me. Initially I was going to write the "Watcher Service"
to poll the ServiceControlManager at periodic intervals, but I want to
know why and when the state of the "Listener Service" changes. A
polling service doesn't provide that level of detail.
 
C

Christian Garcia

I checked on the info you provided and the services and installer
classes all have unique names. I can even start and stop the "Listener
Service" through the MMC or shell with a NET command and once running
it'll handle MSMQ Message arrival without any errors. The problem is
when I try to start that service from within the "Watcher Service". Am
I trying to do something that the .NET Framework doesn't support???
cmgarcia,
You can use this pattern to debug a windows service without it being
installed. It should be self-explanatory:

// The main entry point for the process
static void Main()
{
#if (!DEBUG)
System.ServiceProcess.ServiceBase[] ServicesToRun;
ServicesToRun = new System.ServiceProcess.ServiceBase[] { new Service1() };
System.ServiceProcess.ServiceBase.Run(ServicesToRun);
#else
// debug code: allows the process to run as a non-service
// will kick off the service start point, but never kill it
// shut down the debugger to exit
Service1 service = new Service1();
service.();
System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);
#endif
}

========================================
Possibly the problem you describe is caused by forgetting to make both the
service and the installer classes all have distinct, separate service names?
Peter

--
Co-founder, Eggheadcafe.com developer portal:
http://www.eggheadcafe.com
UnBlog:
http://petesbloggerama.blogspot.com




I have two windows services that I've written: the first is a "Listener
Service" that listens for MSMQ Message delivery. The second is a
"Watcher Service" that monitors the state of the first. If the
"Listener Service" goes down I want the "Watcher Service" to receive a
notification and perform a set action.

To enable this communication I've written a separate assembly (that
both services reference) that exposes two interfaces :
IServiceStatePublisher and IServiceStateSubscriber. The way that I
register the "Watcher Service" as a subscriber to the "Listener
Service" is with the following code in the OnStart event of the
"Watcher Service"::

protected override void OnStart(string[] args)
{
//Line 1
ServiceBase qw = new QueueWatcher();
//Line 2
((IServiceStatePublisher)fd).addSubscriber((IServiceStateSubscriber)this);
//Line 3
ServiceBase.Run(qw);
}

I thought it reasonable that this would work, however, when I start the
"Watcher Service" the Application Event log shows the message "Service
cannot be started. An instance of the service is already running". I've
determined that the error is specific to the code at Line 3, but I
can't identify the reason it's happening. Neither service is running
when the "Watcher Service" is started and I don't have the ability to
step into the ServiceBase code to see what's going on there.

I'm stumped, so any help is greatly appreciated.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top