玄铁剑

成功的途径:抄,创造,研究,发明...
posts - 128, comments - 42, trackbacks - 0, articles - 174

How to Create a Simple Polling Service

Posted on 2007-01-03 22:29 玄铁剑 阅读(405) 评论(0)  编辑 收藏 引用 所属分类: Service

Introduction

This article describes step-by-step, with screen snapshots, how to create a polling service using VB.NET and Visual Studio 2005. It solves the problem of using timers in a service in a quick and simple manner.

Background

Over the years I have leaned on Code Project to help me get started on many projects that involved programming technologies I was not familiar with at the time. This last project required me to create a service for a set of code I had already written. So I headed over to Code Project to figure out if my friends at Code Project had a good article to do that. I was not disappointed. Mahmoud Nasr had written a highly rated and popular article Simple Windows Service Sample.

Everything went fine until I needed to add the timer part. There are a great many opinions about which timers to use in a service. And a Google search will yield many requests and complaints about all of them. I never did find a satisfactory article that explained how to do this seemingly simple thing. In addition, there were issues with multithreading and reentrancy when the timer fires before your task is ready to start over again.

So I think I have solved this with a simple and quick solution. So if you want to run a task repeatedly in the background, without worrying about reentrancy, or multiple threading. If you just want to wrap your code in a Windows Service. Here is a very simple straight forward way to do it.

Using the code

The code I present, basically follows the same steps to create a service that MSDN recommends. And is very similar to Mahmoud's article. The main difference being that it includes code to do polling and shows you where you can drop your code in.

Executing the demo will install a service called "Polling Service". It will write an event log entry to the Application Log on your computer every 30 seconds. The source code is everything you need to build the demo. It is also the final result of following the steps in this article.

1. Create New Service Project

Start by creating a new Visual Studio Project. Startup Visual Studio 2005.

Select the "Windows Service" template and name the project.

Drag and drop the "Event Log" component from the toolbox onto your new service designer window.

Set the "ServiceName" and "(Name)" property to the name of your new service.

Set the "Log" property to "Application". Set the "Source" property to the name of your new service.

Enter the wrapper code for your service.

You can cut and paste the following code into the code window for your service. Change variable names and message text as appropriate for your service.

Collapse
Imports System.Threading

Public Class PollingService
    ' Keep track of worker thread.
    Private m_oPollingThread As New Thread( _
        New System.Threading.ThreadStart(AddressOf PollProcess))

    Protected Overrides Sub OnStart(ByVal args() As String)
        ' Add code here to start your service. This method should set things
        ' in motion so your service can do its work.
        EventLog1.WriteEntry("PollingService is starting.")

        ' Start the thread.
        m_oPollingThread.Start()
    End Sub

    Protected Overrides Sub OnStop()
        ' Add code here to perform any tear-down necessary to stop your service.
        EventLog1.WriteEntry("PollingService is stopping.")

        ' Stop the thread.
        m_oPollingThread.Abort()
    End Sub

    Private Sub PollProcess()
        ' Loops, until killed by OnStop.
        EventLog1.WriteEntry("PollingService service polling thread started.")
        Do
            ' Wait...
            System.Threading.Thread.Sleep(30000) ' 30000 = 30 seconds

            PollingPass()
        Loop
    End Sub

    Private Sub PollingPass()
        Try
            ' Do Stuff Here...
            EventLog1.WriteEntry("PollingService service polling pass executed.")
        Catch ex As System.Exception
            EventLog1.WriteEntry("PollingService encountered an error '" & _
                ex.Message & "'", EventLogEntryType.Error)
            EventLog1.WriteEntry("PollingService service Stack Trace: " & _
                ex.StackTrace, EventLogEntryType.Error)
        End Try
    End Sub

End Class

Notes About the Code

When the service is started, in the "OnStart" method, a new thread is started. You must start a new thread because the service manager controls this process. If you simply called the polling process from the OnStart method, the service mananger would complain that the service does not respond. In other words, the OnStart method did not return control to the service manager.

That new thread loops indefinitely and the only way to stop it is to issue the Abort command on the thread, which we do when we stop the service in the "OnStop" method.

The thread process continually executes two commands. The command to wait for a specified period of time. And then the command to run your code.

In my example, I have added exception checking to write any problems to the event log. The event log is the only way to debug a service during the startup time, as you can only interactively debug a service by attaching to the process "AFTER" it has already started.

That's it for your service. Pretty simple, eh? Replace the comment "Do Stuff Here..." with the code you want to run on a periodic basis.

You can change the period that the service waits between executing your code by changing the sleep time. It is specified in milliseconds, there's 1000 milliseconds in one second.

2. Add Project Installer

The service is done. However, to run it we can't just press the F5 button. We have to install the service. The following describes how to include in the project all the "stuff" needed to install the service on a computer.

Right click on the designer pane for your service and select the option "Add Installer".

Everything is setup for you. You can choose how your service starts by setting the "StartType" property. The default is "Manual". I've set it to "Automatic" in my example.

You can also specify which account the service runs under when it is started. Select the "ServiceProcessInstaller" component and set the "Account" property. The default is "User Account" and you will need to specify the username and password at installation time. I have set the example to use "LocalSystem" which does not require a username or password. Most Windows services run this way.

Ok, now when your application is run using the /install option, it will install itself as a service on your computer. And when /uninstall is specified it will remove the service from your computer.

Now all we have to do is build the thing and resolve any build errors. To do that, select the properties of "My Project" in the Solution Explorer.

Change the "Startup Object" to the name of your service.

Now build your solution.

3. Add Setup Project

OK, you have a service, let's add a setup procedure to this project to make it easy for others to install and use your funky new service.

Choose the "Setup Wizard" and choose a name. You can use the same name as your setup project.

Follow the setup wizard prompts.





Now you need to add a custom action so that after all the files are copied over the program is setup as a service.



We are done setting up the setup project. Now build it.

4. Run It





Your service has been installed. Now go to the Service Manager and start it. The Service Manager can be found in "Administrative Tools".

Start the service. Even though we set it to start automatically. It does not start automatically after we install the service. It will start automatically when the computer starts up.

Now examine the event log to verify our service started and is running successfully. The Event Viewer can be found in "Administrative Tools".

5. Notes on uninstall

This example will continue to write event log messages to your application log every 30 seconds. Once you are convinced it works you will want to uninstall it.

To do that simply run the same .msi file that you ran to install it in the first place. It will prompt to repair or remove. Choose the remove option.

Another way to remove your service is through the Add/Remove Software Control panel option. If you have lost or overwritten your .msi file with a new version, this is the only way to remove your service.

BEFORE UNINSTALLING A SERVICE: be sure to close the Services Viewer. If you do not and you have your service highlighted in the Service Viewer the uninstall will not be able to remove your service. This is because the Service Viewer "locks" the service that is highlighted. The uninstaller will instead "mark" the service for deletion. When this happens you cannot reinstall the service until the marked service is removed. There is no way to remove the marked service except by restarting the computer.

Mark James Newman


Click here to view Mark James Newman's online profile.

只有注册用户登录后才能发表评论。