Poblema servizio WINDOWS che si stoppa senza richiesta

mercoledì 04 dicembre 2013 - 09.11
Tag Elenco Tags  C#  |  .NET 4.0  |  Visual Studio 2010  |  Visual Studio Express

yag Profilo | Junior Member

salve

ho un problema con una winservice in pratica ho implementato una classe che con intervalli stabiliti da un timer
legge dei dati da una classe (un mockup per uno strumento) e li salva in un file

il problema e che questo servizio ogni tanto si stoppa

nel log che scrive (fatto da me) vedo il metodo in cui si ferma e non noto niente di particolare

mi chiedevo se c'era un modo nell'evento

protected override void OnStop()

del servizio di sapere chi era il chiamante .. per poter avere più informazione sul problema

grazie

Vash Profilo | Junior Member

salve,
il servizio potrebbe andare in eccezione quando fa delle elaborazioni, ovvero quando il timer richiama il metodo che si preoccupa di leggere e scrivere i dati.
se non lo hai già fatto ti consiglierei di guardare l'event viewer di Windows per ottenere delle info in più!
spero ti possa essere utile.

ciao

yag Profilo | Junior Member

grazie

in parte credo di aver risolto in parte no!

nel senso credo di aver capito il problema ma non so bene come risolverlo

Dunque dentro il mio servizio ho alcune linee di codice che scrivono dentro un file di log:

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

ho notato che quando la macchina è molto carica ci sono tanti programmi aperti etc... la scrittura dei dati nel file di log viene
ritardata quindi quando vado a scriverci la volta successiva mi viene dato il messaggio che il file è bloccato da un'altro processo e non può scriverci

come potrei risolvere questo problema ?

grazie

Vash Profilo | Junior Member

prima di richiamare AppendText del file, ti suggerirei di testare se è aperto oppure no.

Metodo per testare il file:
bool IsFileOpen(FileInfo file) { FileStream stream = null; try { stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None); } catch (IOException) { // File già aperto da un'altra applicazione. return true; } finally { if (stream != null) stream.Close(); } // Il File non è aperto. return false; }

da qui richiami il metodo:
Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

ciao

yag Profilo | Junior Member

ottimo il consiglio

ma se il file è ancora aperto salto il dato da scriver nel ?
no mi ero mai confrontato con questo problema ....

stavo valutando di usare sql server ce ma volevo rendere "leggibile il log immediatamente non so ...

Vash Profilo | Junior Member

Un dubbio: ma il file viene usato anche da qualche altra applicazione?
Se sì allora risulta difficile scriverci sopra quando questo è aperto!
Altrimenti dovresti verificare il motivo per cui non te lo chiude all'uscita della "using". io solitamente apro il file all'avvio del servizio, gli imposto l'AutoFlush (così il buffer viene svuotato sempre sul file senza che venga per forza riempito), e alla fine chiudo il file alla chiusura del servizio
protected override void OnStop()

yag Profilo | Junior Member

non non vineene usato da altro o programma e non capisco il motivo per cui non lo chiude

il servizio deve girare 24h nn posso tenerlo sempre aperto ...

cosa è l'autoflush ?

Vash Profilo | Junior Member

Normalmente quando scrivi dei dati all'interno di un file viene usato un buffer che finchè non si riempe, i dati non vengono scritti sul disco ma rimangono in memoria, quindi la scrittura avviene solo quando questo buffer si riempe oppure alla chiusura del file stesso (metodo Close()). L'AutoFlush è una proprietà dello StreamWriter la quale indica che ad ogni chiamata del metodo Write svuota automaticamente il buffer senza aspettare che sia pieno e/o venga chiamato il metodo Close(); perciò anche se il file è ancora aperto dall'applicazione, e tu provi ad aprirlo con notepad per esempio, vedrai tutti i dati scritti nel file. ...non so se sono stato chiaro!!
A questo punto invece di questo pezzo di codice
Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra
prova a usare questo:
StreamWriter w = new StreamWriter(this.clsDatiFileIniService.PathLog + "\\STRUMETS_SERVICE_" + DateTime.Now.Day.ToString() + "_" + DateTime.Now.Month.ToString() + "_" + DateTime.Now.Year.ToString() + ".TXT", true); w.WriteLine(Properties.Settings.Default.NomeServizio + StringaDaLoggare); w.Close();

yag Profilo | Junior Member

ok diciamo che usando l'autoflush gestisce lui la scrittura etc
ma se io sono dentro un servizio tenere sempre istanziato lo stream tipo lo creo nel costruttore è una buona soluzione ?
dall'using dovrebbe uscire ma sicuramente va in conflitto perchè dentro girano dei timer e quindi non quando ci sono dei rallentamenti
sta scrivendo e poi viene chiamato un'altro metodo che scrive qualcos'altro nel log...

Vash Profilo | Junior Member

>ma se io sono dentro un servizio tenere sempre istanziato lo
>stream tipo lo creo nel costruttore è una buona soluzione ?
E' una buona soluzione sì: in questo modo aprirai il file di testo una sola volta all'avvio del servizio, il file sarà accessibile in scrittura per tutta la durata dell'applicazione, e chiuderai il file allo stop del servizio.
Ovviamente dichiari lo stream in una variabile visibile dall'intera applicazione e tutti i timer potranno accodare dati al file.

>dall'using dovrebbe uscire ma sicuramente va in conflitto perchè
>dentro girano dei timer e quindi non quando ci sono dei rallentamenti
>sta scrivendo e poi viene chiamato un'altro metodo che scrive
>qualcos'altro nel log...
Per questo caso, se un timer sta già scrivendo nel file e non ti interessa che ci ripassi un'altra volta quando quest'ultimo non ha ancora finito, potresti fermare il timer all'inizio dell'elaborazione e poi farlo ripartire alla fine dell'elaborazione.

yag Profilo | Junior Member

ok si ho fatto cosi ma il close lo posso fare alla chiusura del servizio ?
teoricamente mai oppure dopo ogni scrittura...

Vash Profilo | Junior Member

Sì lo fai alla chiusura del servizio.

yag Profilo | Junior Member


ok perfetto
un ultima cosa diciamo ... io vorrei creare un log al giorno quindi in pratica ogni giorno dovrei chiudere il file e aprirne un'altro
sulla variabile a livello di classe devo fare il dispose ?

Vash Profilo | Junior Member

Ne ho già creato uno che utilizzo in molti progetti con servizi che girano 7 giorni su 7.
Prova questo, lo inserisci prima della riga che scrive sul file:
Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

La variabile lastLogDate, la prima volta, la inizializzi con la data attuale nel tuo costruttore dove inizializzi lo StreamWriter.

ciao

yag Profilo | Junior Member

Ottimo grazie
Mille avevo pensato proprio una soluzione simile
Tanks
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2025
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5