2010-06-17 15 views

Répondre

9

Vous pouvez utiliser un BackgroundWorker pour effectuer votre opération de longue durée en réponse à l'événement Service.Start.

Il est assez facile de le faire dans la méthode OnStart() de votre classe dérivée ServiceBase. Il y a aussi un good example on MSDN raisonnable.

protected override void OnStart(string[] args) 
{ 
    var worker = new BackgroundWorker(); 
    worker.DoWork += DoSomeLongOperation; 

    worker.RunWorkerAsync(); 
} 

private void DoSomeLongOperation(object sender, DoWorkEventArgs e) 
{ 
    // do your long operation... 
} 

Notez que vous pouvez également vous abonner aux ProgressChanged et RunWorkerCompleted événements, de sorte que vous pouvez informer le gestionnaire de contrôle de service de vos progrès et démarrage succès (ou l'échec).

1

Je dois aussi faire ceci: je lance un thread au démarrage qui fait toute son initialisation et définit un 'isInitialized' privé à true quand il est fini. Le service effectue des actions périodiquement (c.-à-d. Sur une minuterie) et ne commencera pas ces actions si isInitialized n'est pas défini sur true.

1

Nous utilisons généralement une minuterie simple pour réaliser cette fonctionnalité. Nous allons mettre le minuteur dans le service OnStartup, laisser le service répondre au gestionnaire de contrôle de service, puis laisser la minuterie démarrer le processus après quelques secondes. Ce processus peut aller dans un fil séparé ou non en fonction de ce qui doit être fait. La minuterie peut être réutilisée si ce processus doit se produire à intervalles réguliers.

0

La meilleure façon pragmatique est de créer un fil de travail.

En général existe une autre manière documentée, que je peux expliquer sur l'exemple du code non managé. Pendant l'initialisation, un service Windows dispose d'un peu de temps pour le faire. Cette période peut changer quelque part dans le registre. Si besoin de service plus si peut appeler

SetServiceStatus avec dwCurrentState=SERVICE_START_PENDING certains dwCheckPoint et dwWaitHint, de SERVICE_STATUS struct rempli de sorte que dwWaitHint est le temps estimé nécessaire pour une opération de démarrage en attente en millisecondes. Avant que la durée spécifiée ne soit écoulée, le service doit appeler la fonction SetServiceStatus avec une valeur dwCheckPoint incrémentée ou une modification dans dwCurrentState. Voir la description de dwWaitHint sur http://msdn.microsoft.com/en-us/library/ms685996(VS.85).aspx.

1

J'ai également eu ce problème avec un service Windows. Je pense que vous devez garder la logique d'initialisation sous 30 secondes, sinon le gestionnaire de services Windows arrêtera le service. Ce que j'ai fait était assez simple. J'ai créé une méthode où je mettais toute la logique lourde qui devait être exécutée et ensuite j'ai créé une minuterie qui cocherait après 20 secondes et exécuterait cette méthode. Ainsi, le service démarre, puis crée la minuterie, l'initialise avec un intervalle de 20 secondes et termine l'initialisation. Après 20 secondes, la minuterie cochera et lancera la logique métier de l'application. Bien sûr, vous pouvez spécifier l'intervalle de temps que vous voulez.

Vous devez déclarer la minuterie comme un paramètre de la classe:

public partial class YourService: ServiceBase 
{ 
    System.Timers.Timer tmrOnStart; 

initialisez la minuterie dans la méthode OnStart

protected override void OnStart(string[] args) 
{ 
    //set the interval to 20 seconds 
    tmrOnStart = new Timer(); 
    tmrOnStart.Interval = 20000; 
    tmrOnStart.Enabled = true; 
    tmrOnStart.AutoReset = false; 
    tmrOnStart.Elapsed += new ElapsedEventHandler(tmrOnStart_Elapsed); 
    tmrOnStart.Start(); 
} 

Lorsque la minuterie déclenche l'événement Elapsed, il exécutera cette méthode:

void tmrOnStart_Elapsed(object sender, ElapsedEventArgs e) 
{ 
    heavyBusinessLogicMethod(); 
} 

Et vous auriez à mettre votre logique dans le heavyBusine Méthode ssLogicMethod.