Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

One of the components of my company's product is a Windows service, written in C#. It's dependent on .NET and on a few other libraries, none especially large. It works perfectly when started normally, but doesn't start automatically when the system is booted, even though we configured it to.

This is because there's a thirty second time limit on service startup: if your service takes more than 30 seconds to load, Windows gets bored and kills it. The usual solution is ServiceBase.RequestAdditionalTime(), but that won't help us here: we're getting killed before any of our code even runs, because all our dependencies take so long to load. It's possible to increase this timeout globally by setting HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\ServicesPipeTimeout, but that's pretty gross. What if someone else is also hitting that setting? What if we don't have the right permissions?

I don't really want to "solve" this in the registry, but it seems like we might have no choice. Is there a better way to approach this problem?

share|improve this question

migrated from stackoverflow.com Feb 9 '10 at 9:26

This question came from our site for professional and enthusiast programmers.

    
By dependencies I assume you mean assemblies your application depends on, if so, are most of your application code in the service executable or is it held in another assembly? Say, you have Company.Foo.StuffService which loads Company.Foo.App (and which in turn contains most of the application code)? –  Skurmedel Feb 8 '10 at 21:50
2  
Exactly what dependencies do you have that takes 30 seconds? It's not the .Net libraries; those are pretty fast. Something else is going on here. –  Chris Lively Feb 8 '10 at 22:05
2  
Use Linux? </snark> –  Mark Ransom Feb 8 '10 at 22:27
2  
Use "delayed start" for it so it's not competing with other boot-time inits? –  Oskar Duveborn Feb 9 '10 at 10:04
    
The code in various good-quality replies here should be a big clue that this post doesn't belong on serverfault. –  Chris Thorpe Oct 7 '10 at 23:41
add comment

10 Answers 10

We had a service that took a while to get started. Our fix was to spawn a thread and return immediately from the OnStart method. I'm not sure how well this will play with your dependencies issue, but it's certainly one way of sidestepping the 30second limit:

    protected override void OnStart(string[] args)
    {
        var thread = new Thread(() =>
        {
            svc = ServiceFactory.Create(foo);
        })
        {
            IsBackground = true
        };
        thread.Start();
    }

For anything other than trivial, some synchronization primitives will probably be needed.

share|improve this answer
    
I've done this a few times as well with both unmanaged and managed code. For a service, the only tricky aspect is thread management. –  Rob Sanders Feb 8 '10 at 22:01
    
This will not help if none of the openers code gets the chance to execute. –  Daniel Brückner Feb 8 '10 at 22:09
    
Is it possible to write a native service that will return quickly after spawning off the appropriate managed logic? –  Greg D Feb 8 '10 at 22:24
add comment

I cannot really imagine this scenario but if no of your code runs at all, all the time must be spend loading assemblies and initializing types. Double check all possible and impossible other error sources. If you cannot find anything at all, try intercepting the assembly loading events of the application domain. If it turns out that all the time is really spend loading assemblies, you could think about starting the core service in a separate application domain. Still quite a hack, but it will keep the main application domain alive while the secondary application domain is loading the assemblies.

share|improve this answer
add comment

As others have noted, this does sound like one or more of your dependencies are taking way too long to initialise. I'd suggest firstly trying to set up your service so that it can run as a foreground process if you specify a flag (eg see my previous post) and then use the 'profile' mode of the dependency walker which should give you a timestamped diagnostic of which dlls are taking the time. If one of the processes is hanging for a while then you might find adplus running in 'hang' mode useful.

share|improve this answer
add comment

If you own the dependent services, you can rewrite them to behave better. If you can't do that, you could try setting their start type to SERVICE_AUTO_START to see if that will start them before your service. Failing that you could try configuring the ServiceGroupOrder and GroupOrderList registry keys, but this is a bit complicated.

share|improve this answer
add comment

Can't you put all the code you can from your service in a separate assembly, create a "service"-class, then load that assembly in your real service and instantiate the class with reflection? That would defer loading the assemblies until your service is in control.

A little grotesque though.


Example

// Application assembly
class ServiceImplementation
{
   public void Run(...) { ... }
}

// Inside "proper" Service executable/assembly
void Run()
{
   var appAssembly = Assembly.Load("ApplicationAssembly");
   Type implType = appAssembly.GetType("ServiceImplementation");
   object serviceImplementation = Activator.CreateInstance(implType);
   // Do reflection on serviceImplementation to get Run-method and call it,
   // etc.
}
share|improve this answer
add comment

That is very strange as others have already mentioned. As an example I develop a windows service hosting a few WCF services. It caches stuff from databae and AD and then opens the endpoints. All this typically completes very well. The WCF, Log4Net, EntLib and ODP.Net assemblies are loaded during service startup. Only in rare cases in test environments we get some timeouts.
So you take more than 30secs to load dependencies doesn't sound right.

share|improve this answer
add comment

There is no real way to deal with this, the ordering of the services is crucial to the running of the services themselves..as I recall I remember seeing a utility to re-order based on the priority of which services gets to run first... Have a look here.

Hope this helps, Best regards, Tom.

share|improve this answer
add comment

What about separating out all of your logic from the start and then spawn it into using a background thread and MEF?

share|improve this answer
add comment

.Net 2.0 can be slow to check certificates, which makes services slow to start. Follow this KB on how to bypass those checks to make apps start faster: http://support.microsoft.com/kb/936707

share|improve this answer
add comment

If you server uses xp, you can use the suggestion here. That might help. If you have anything after xp, use the delayed startup and see if that fixes your issue.

http://support.microsoft.com/kb/193888

share|improve this answer
1  
It's helpful to supply the answer here, on-site, instead of just linking to an external site. –  Drew Khoury Jan 9 at 22:15
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.