2010-02-22 18 views
5

Sto per implementare la soluzione archivistica FileSystemWatcher. Ho una directory per monitorare le creazioni di file e il compito di risucchiare i file creati e inserirli in un DB. Approssimativamente ciò comporterà la lettura e l'elaborazione di 6 o 7, 80 file di testo char che appaiono ad una velocità di 150 mS in raffiche che si verificano ogni due secondi, e raramente si dovrà elaborare anche un file binario da 2 MB. Molto probabilmente sarà un processo 24 ore su 24, 7 giorni su 7.Dopo l'avvio di FileSystemWatcher - Thread Pool o thread dedicato?

Da ciò che ho letto sull'oggetto FileSystemWatcher è meglio accodare i suoi eventi in un thread e quindi rimuoverli/elaborarli in un altro thread. Il dilemma che ho adesso è quale sarebbe il miglior meccanismo di creazione del thread che esegue l'elaborazione. Le scelte che posso vedere sono:

  1. Ogni volta che ricevo un evento FSW creo manualmente un nuovo thread (sì lo so .. architettura stupido, ma dovevo dirlo).

  2. Gettare l'elaborazione al pool di thread CLR ogni volta che ricevo un evento FSW

  3. In avvio, creare un secondo thread dedicato per l'elaborazione e l'uso di un modello produttore/consumatore per gestire il lavoro. Il thread principale accoda la richiesta e il secondo thread la abbandona ed esegue il lavoro.

sto tendente al terzo metodo, come quello preferito come so che sarà sempre richiesto il filo di lavoro - e probabilmente anche di più perché non ho confidenza con il pool di thread.

risposta

3

Se sa che sarà sempre necessario il secondo filo, e anche voi sapete che non avrai mai bisogno di più di un thread di lavoro, quindi l'opzione tre è abbastanza buono.

+1

+1, vorrei aggiungere che l'uso del pool di thread proverà a gestire le richieste simultaneamente su più thread che non sembrano una buona cosa per la vostra applicazione. –

+0

Anon .. Da quello che ho fatto la mia elaborazione dovrebbe essere fatta bene e veramente nei 150mS tranne nel caso dell'elaborazione del file binario - che funzionerà a circa 150mS ma dovrebbe essere un evento talmente raro che ci sarà un sacco di tempo di recuperare se le cose vengono messe in coda. –

2

Tieni presente che FileSystemWatcher potrebbe perdere eventi, non c'è alcuna garanzia che invierà tutti gli eventi specifici che sono stati trasmessi. Il tuo progetto di mantenere il lavoro svolto dagli eventi di ricezione del thread al minimo, dovrebbe ridurre le possibilità che ciò accada, ma è ancora una possibilità, data la dimensione del buffer di eventi finiti (massimo di 64 KB).

Si consiglia vivamente di sviluppare una batteria di test di tortura se si decide di utilizzare FileSystemWatcher.

Durante i test, abbiamo riscontrato problemi con le posizioni di rete, che la modifica di InternalBufferSize non è stata risolta, tuttavia, quando abbiamo riscontrato questo scenario, non abbiamo ricevuto neanche le notifiche degli eventi di errore.

Così, abbiamo sviluppato il nostro meccanismo di polling per farlo, usando Directory.GetFiles, seguito confrontando lo stato dei file restituiti con lo stato precedentemente sottoposto a polling, assicurando che avessimo sempre un delta accurato.

Naturalmente, questo ha un costo notevole in termini di prestazioni, che potrebbe non essere sufficiente per voi.

+1

Leon, sono a conoscenza dei limiti e dei problemi della FSW. Sembra non solido sulle condivisioni di rete. Sto solo usando una directory locale e non mi aspetto che la dimensione del buffer degli eventi di FSW mi causi problemi. Sto pianificando un processo di spazzamento solo nel caso mi manchi qualcosa. –

+0

Leon .. BTW Pianificherò un sacco di test .. FSW sembra avere un enorme numero di trucchi nascosti. –

+0

Se lo stavo facendo, andrei a fare il FSW ed eseguirò una scansione completa sulla directory di tanto in tanto (forse ogni giorno, in un momento il sistema è normalmente silenzioso?) Per assicurarmi che tutto venga catturato. –

3

La terza opzione è la più logica.

Per quanto riguarda FSW mancano alcuni eventi di file, ho realizzato questo: 1) FSW oggetto che spara su FileCreate 2) tmrFileCheck, zecche = 5000 (5 secondi) - Chiamate tmrFileChec_Tick

Quando l'evento FileCreate verifica, se (tmrFileCheck.Enabled == false) quindi tmrFileCheck.Start()

In questo modo, dopo 10 secondi tmrFileCheck_Tick incendi che a) tmrFileCheck.Stop() b) CheckForStragglerFiles

Dei test che ho eseguito, questo funziona in modo efficace dove ci sono un file < creato al minuto.

Una variante è semplicemente avere un segno di spunta del timer sempre in NN secondi e spazzare la directory (i) per i file in ritardo.

Un'altra variante è assumermi per premere F5 per aggiornare la finestra e chiamarti quando ci sono file in ritardo; solo un suggerimento. :-P

Problemi correlati