2010-06-17 13 views

risposta

9

È possibile utilizzare un BackgroundWorker per eseguire la lunga operazione in risposta all'evento Service.Start.

È abbastanza facile farlo nel metodo ServiceBase -derived del metodo ServiceBase -derived. C'è anche un ragionevole good example on MSDN.

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... 
} 

Si noti che è anche possibile abbonarsi ai ProgressChanged e RunWorkerCompleted eventi, in modo da poter informare il direttore di controllo del servizio dei tuoi progressi e messa in servizio di successo (o il fallimento).

1

Devo fare anche questo: sposto un thread all'avvio che esegue tutta la sua inizializzazione e imposta un privato 'isInitialized' su true al termine. Il servizio esegue le azioni periodicamente (ad esempio, su un timer) e non inizierà quelle azioni se isInitialized non è impostato su true.

1

Generalmente utilizziamo un semplice timer per ottenere questa funzionalità. Imposteremo il timer nel servizio OnStartup, lasceremo che il servizio risponda al Service Control Manager e poi faccia partire il timer dopo alcuni secondi. Quel processo può andare in un thread separato o meno a seconda di ciò che deve essere fatto. Il timer può essere riutilizzato se questo processo deve avvenire a intervalli regolari.

0

Il miglior modo pragmatico è creare un thread di lavoro.

In generale esiste un altro modo documentato, che posso spiegare sull'esempio del codice non gestito. Durante l'inizializzazione, un servizio Windows ha un tempo limitato per farlo. Questa volta può essere cambiato da qualche parte nel registro. Se il servizio ha bisogno di più se può chiamare

SetServiceStatus con dwCurrentState=SERVICE_START_PENDING qualche dwCheckPoint e dwWaitHint, di SERVICE_STATUS struct riempiti in modo che dwWaitHint è il tempo stimato necessario per un'operazione di partenza in attesa in millisecondi. Prima che sia trascorso il tempo specificato, il servizio deve effettuare la chiamata successiva alla funzione SetServiceStatus con un valore incrementato dwCheckPoint o una modifica in dwCurrentState. Vedi la descrizione di dwWaitHint su http://msdn.microsoft.com/en-us/library/ms685996(VS.85).aspx.

1

Ho anche avuto questo problema con un servizio di Windows. Penso che devi mantenere la logica di inizializzazione in 30 secondi, altrimenti il ​​Service Manager di Windows interromperà il servizio.

Quello che ho fatto è stato abbastanza semplice. Ho creato un metodo in cui ho inserito tutta la logica pesante che doveva essere eseguita e quindi ho creato un timer che avrebbe spuntato dopo 20 secondi ed eseguito quel metodo. Quindi il servizio dovrebbe iniziare, quindi creare il timer, inizializzarlo con un intervallo di 20 secondi e quindi terminare l'inizializzazione. Dopo 20 secondi il timer segnerà e avvierà la logica di business dell'applicazione. Naturalmente puoi specificare qualunque intervallo di tempo desideri.

Si dovrebbe dichiarare il timer come parametro della classe:

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

Poi inizializzare il timer nel metodo 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(); 
} 

Quando il timer attiverà l'evento trascorso, esso verrà eseguito questo metodo:

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

E tu dovresti mettere la tua logica in heavyBusine metodo ssLogicMethod.

Problemi correlati