Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. Visual Basic
  4. Services - prevent from being stopped?

Services - prevent from being stopped?

Scheduled Pinned Locked Moved Visual Basic
questioncsharpdatabasehelp
6 Posts 4 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    Mike Mestemaker
    wrote on last edited by
    #1

    I'm building a Service in VB.NET: It's basically watching for a file to appear in a directory; when it does, it processes that file into a database. Depending on the size of the data file, this process can take some time. What I want to be able to do is prevent the Service Control Manager (SCM) from shutting my service down while it's busy. What is the best way to do this? I tried setting Me.CanStop to false on the fly, but found that it can't be changed while the service is running. :( The one idea I've had so far is to create a boolean called isBusy that is set to true while processing and false while idle. Then, in the OnStop event do the following to prevent the stop until the task is done:

    Do While isBusy
    DoEvents
    Loop

    But, then what happens when this exceeds the timeout that the SCM has? The SCM reports an error, but does the service eventually shutdown? My main concern is finding a way for my user to shut the service down without shutting down in the middle of a task. :confused: Thanks for any insight.

    R H E 3 Replies Last reply
    0
    • M Mike Mestemaker

      I'm building a Service in VB.NET: It's basically watching for a file to appear in a directory; when it does, it processes that file into a database. Depending on the size of the data file, this process can take some time. What I want to be able to do is prevent the Service Control Manager (SCM) from shutting my service down while it's busy. What is the best way to do this? I tried setting Me.CanStop to false on the fly, but found that it can't be changed while the service is running. :( The one idea I've had so far is to create a boolean called isBusy that is set to true while processing and false while idle. Then, in the OnStop event do the following to prevent the stop until the task is done:

      Do While isBusy
      DoEvents
      Loop

      But, then what happens when this exceeds the timeout that the SCM has? The SCM reports an error, but does the service eventually shutdown? My main concern is finding a way for my user to shut the service down without shutting down in the middle of a task. :confused: Thanks for any insight.

      R Offline
      R Offline
      Ray Cassick
      wrote on last edited by
      #2

      I don't think that you can prevent the service form being shutdown. If all you are trying to do is preserve the integrity of the data that you are importing you can look into other ways to do this, perhaps locally creating the record set then adding it to the DB (this might be faster then adding it to the DB as you read from the file), or try adding the data to the DB inside of a transaction. That way it can be aborted if someone decides to stop in the middle and you won't get partial processed data.


      Paul Watson wrote: "At the end of the day it is what you produce that counts, not how many doctorates you have on the wall." George Carlin wrote: "Don't sweat the petty things, and don't pet the sweaty things." Jörgen Sigvardsson wrote: If the physicists find a universal theory describing the laws of universe, I'm sure the asshole constant will be an integral part of that theory.


      1 Reply Last reply
      0
      • M Mike Mestemaker

        I'm building a Service in VB.NET: It's basically watching for a file to appear in a directory; when it does, it processes that file into a database. Depending on the size of the data file, this process can take some time. What I want to be able to do is prevent the Service Control Manager (SCM) from shutting my service down while it's busy. What is the best way to do this? I tried setting Me.CanStop to false on the fly, but found that it can't be changed while the service is running. :( The one idea I've had so far is to create a boolean called isBusy that is set to true while processing and false while idle. Then, in the OnStop event do the following to prevent the stop until the task is done:

        Do While isBusy
        DoEvents
        Loop

        But, then what happens when this exceeds the timeout that the SCM has? The SCM reports an error, but does the service eventually shutdown? My main concern is finding a way for my user to shut the service down without shutting down in the middle of a task. :confused: Thanks for any insight.

        H Offline
        H Offline
        Heath Stewart
        wrote on last edited by
        #3

        Once the SCM signals the service to shutdown, it will, event if the SCM doesn't "see" it happen. I recommend you don't use a simple boolean, however. Look at the System.Threading namespace, specifically Mutexes or Monitors. These are much safer to use. Basically, the file parsing / processing procedure and the code snippet you wrote above share a mutex or semaphore (a WaitHandle in most cases in .NET) You would obtain an exclusive lock on the mutex / semaphore before doing all your processing. If close is called it'll wait till it can receive an exclusive lock. The reverse is also true, but that processing proc won't be called when the service is shutdown obviously. Basically, however gets an exclusive lock on the mutex first wins and the other(s) wait until they can get an exclusive lock before running their code. This is far more safe.


        Reminiscent of my younger years... 10 LOAD "SCISSORS" 20 RUN

        M 1 Reply Last reply
        0
        • H Heath Stewart

          Once the SCM signals the service to shutdown, it will, event if the SCM doesn't "see" it happen. I recommend you don't use a simple boolean, however. Look at the System.Threading namespace, specifically Mutexes or Monitors. These are much safer to use. Basically, the file parsing / processing procedure and the code snippet you wrote above share a mutex or semaphore (a WaitHandle in most cases in .NET) You would obtain an exclusive lock on the mutex / semaphore before doing all your processing. If close is called it'll wait till it can receive an exclusive lock. The reverse is also true, but that processing proc won't be called when the service is shutdown obviously. Basically, however gets an exclusive lock on the mutex first wins and the other(s) wait until they can get an exclusive lock before running their code. This is far more safe.


          Reminiscent of my younger years... 10 LOAD "SCISSORS" 20 RUN

          M Offline
          M Offline
          Mike Mestemaker
          wrote on last edited by
          #4

          Thanks for the advice. Let me see if I understand the basic concept: At the beginning of the processing section that I want to be "uninterruptible": Try    Dim M As New Threading.Mutex(True, "myUniqueCode")    ' do the processing Finally    M.Close() End Try In the OnStop event Dim M As New Threading.Mutex(True, "myUniqueCode") Do Until M.WaitOne(1000, False) Loop M.Close() 'do any resource cleanup here Related question: What is the correct way to shut down my service from within it's own code? For example, if my service encounters a condition that tells it to end (other than the SCM's stop command), how does it shut itself down cleanly? I read somewhere that the END command is considered bad form for services. Long term, my application will consist of multiple services (each with their own uninterruptable sections). Some will be more sensitive to this issue than others. I'm thinking of creating an applet that will send a message to each of them and they will shut themselves down when they are free from whatever they were doing). The applet can show the status of each one in turn so the user can watch them shutting down and know when it is safe to proceed.

          H 1 Reply Last reply
          0
          • M Mike Mestemaker

            I'm building a Service in VB.NET: It's basically watching for a file to appear in a directory; when it does, it processes that file into a database. Depending on the size of the data file, this process can take some time. What I want to be able to do is prevent the Service Control Manager (SCM) from shutting my service down while it's busy. What is the best way to do this? I tried setting Me.CanStop to false on the fly, but found that it can't be changed while the service is running. :( The one idea I've had so far is to create a boolean called isBusy that is set to true while processing and false while idle. Then, in the OnStop event do the following to prevent the stop until the task is done:

            Do While isBusy
            DoEvents
            Loop

            But, then what happens when this exceeds the timeout that the SCM has? The SCM reports an error, but does the service eventually shutdown? My main concern is finding a way for my user to shut the service down without shutting down in the middle of a task. :confused: Thanks for any insight.

            E Offline
            E Offline
            ekareem
            wrote on last edited by
            #5

            Hi, I would suggest a different approach. Let the service start a separate program with the file name as a parameter. Let that program deal with the database as long as it needs to. By doing this your service can do its new function regardless of the the file size. Of course I am assuming that a service can launch an application - I may be wrong. Regards Ekareem.

            1 Reply Last reply
            0
            • M Mike Mestemaker

              Thanks for the advice. Let me see if I understand the basic concept: At the beginning of the processing section that I want to be "uninterruptible": Try    Dim M As New Threading.Mutex(True, "myUniqueCode")    ' do the processing Finally    M.Close() End Try In the OnStop event Dim M As New Threading.Mutex(True, "myUniqueCode") Do Until M.WaitOne(1000, False) Loop M.Close() 'do any resource cleanup here Related question: What is the correct way to shut down my service from within it's own code? For example, if my service encounters a condition that tells it to end (other than the SCM's stop command), how does it shut itself down cleanly? I read somewhere that the END command is considered bad form for services. Long term, my application will consist of multiple services (each with their own uninterruptable sections). Some will be more sensitive to this issue than others. I'm thinking of creating an applet that will send a message to each of them and they will shut themselves down when they are free from whatever they were doing). The applet can show the status of each one in turn so the user can watch them shutting down and know when it is safe to proceed.

              H Offline
              H Offline
              Heath Stewart
              wrote on last edited by
              #6

              Actually, this probably wouldn't work. Since you're requesting initial ownership in the same thread, the call to WaitOne() (or its equivalent in the constructor that requests initial ownership) will pass. Read the docs on Mutexes and you'll see that a thread can request access to a Mutex multiple times without blocking. I'm not sure how you're threading your file processing procedure (which is a good idea to do, btw), but doing them in the same thread would not work. Instead, take a look at the SyncRoot keyword in Visual Basic. Basically, declare a shared variable somewhere in your class:

              Private Shared syncRoot As Object = New Object()

              Then, in both methods, you can do the following (although there's no timeout, but these keywords boil down to a Monitor at compile time, so take a look at that for more details):

              SyncLock (syncRoot)
              ' Do work
              End SyncLock

              Hope this helps.


              Reminiscent of my younger years... 10 LOAD "SCISSORS" 20 RUN

              1 Reply Last reply
              0
              Reply
              • Reply as topic
              Log in to reply
              • Oldest to Newest
              • Newest to Oldest
              • Most Votes


              • Login

              • Don't have an account? Register

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • World
              • Users
              • Groups