15.02.2015 Views

C# 4 and .NET 4

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Creating a Windows service Program ❘ 677<br />

class is created <strong>and</strong> passed as the first element to the ServicesToRun array. If more than one service should<br />

run inside this service process, it is necessary to add more instances of the specific service classes to the<br />

array. This array is then passed to the static Run() method of the ServiceBase class. With the Run()<br />

method of ServiceBase, you are giving the SCM references to the entry points of your services. The main<br />

thread of your service process is now blocked <strong>and</strong> waits for the service to terminate.<br />

Here is the automatically generated code:<br />

/// <br />

/// The main entry point for the application.<br />

/// <br />

static void Main()<br />

{<br />

ServiceBase[] ServicesToRun;<br />

ServicesToRun = new ServiceBase[]<br />

{<br />

new QuoteService()<br />

};<br />

ServiceBase.Run(ServicesToRun);<br />

}<br />

code snippet QuoteService/Program.cs<br />

If there is only a single service in the process, the array can be removed; the Run() method accepts a single<br />

object derived from the class ServiceBase, so the Main() method can be reduced to this:<br />

ServiceBase.Run(new QuoteService());<br />

The service program Services.exe includes multiple services. If you have a similar service, where more<br />

than one service is running in a single process in which you must initialize some shared state for multiple<br />

services, the shared initialization must be done before the Run() method. With the Run() method, the main<br />

thread is blocked until the service process is stopped, <strong>and</strong> any following instructions would not be reached<br />

before the end of the service.<br />

The initialization shouldn’t take longer than 30 seconds. If the initialization code were to take longer than<br />

this, the SCM would assume that the service startup failed. You need to take into account the slowest<br />

machines where this service should run within the 30-second limit. If the initialization takes longer, you<br />

could start the initialization in a different thread so that the main thread calls Run() in time. An event<br />

object can then be used to signal that the thread has completed its work.<br />

service start<br />

At service start, the OnStart() method is called. In this method, you can start the previously created socket<br />

server. You must reference the QuoteServer assembly for the use of the QuoteService. The thread calling<br />

OnStart() cannot be blocked; this method must return to the caller, which is the ServiceMainCallback()<br />

method of the ServiceBase class. The ServiceBase class registers the h<strong>and</strong>ler <strong>and</strong> informs the SCM that<br />

the service started successfully after calling OnStart():<br />

protected override void OnStart(string[] args)<br />

{<br />

quoteServer = new QuoteServer(<br />

Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "quotes.txt"),<br />

5678);<br />

quoteServer.Start();<br />

}<br />

code snippet QuoteService/QuoteService.cs<br />

www.it-ebooks.info

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!