Come monitorare un programma di lunga durata a livello di codice


11

Quello che ho attualmente può essere riassunto con questo pseudo codice:

public static void Main(string[] args)
{
    var listOfObjects = Database.GetObjectsToUploadToOnlineService();
    Parallel.ForEach(Upload)
}

private static void Upload(MyUploadObject obj)
{
    //Build object (takes a few milliseconds)
    //Format to JSON (takes a few more milliseconds)
    //Upload (can take up to a max of 10 minutes)
    //Wait for a response (can take up to a max of 10 minutes)
    //Save response to our database (takes a few milliseconds)
}

Questo programma è appena impostato sul nostro server come attività pianificata. Possediamo il programma e possiamo fare ciò che vogliamo con esso. La mia domanda nasce da un blog sull'esecuzione di controlli di monitoraggio automatizzati (non ho un link a portata di mano).

Questo mi ha fatto pensare: come posso modificare il mio programma in modo da poter avviare un altro programma di "monitoraggio"? O dovrebbe cambiare questo da essere un programma console a dire un programma WPF nascosto?

Nel complesso, preferirei essere in grado di eseguire solo un programma sul mio computer che controlla l'avanzamento del programma attraverso la rete, quindi non devo eseguire il RDP nel server per verificarne lo stato (ma non lo farebbe essere la fine del mondo).

Nel complesso, suppongo che mi piacerebbe vedere una finestra che dice qualcosa del tipo: Elaborazione x di y finora, i seguenti elementi sono in fase di elaborazione. Elenca gli elementi in, ad esempio, una tabella e falli dire "Caricamento in corso" o "In attesa di risposta". Forse se impazzisco potrei anche capire come fare una fila di oggetti falliti (ma sarebbe solo extra).

La mia mente continua ad inclinarsi verso un evento, ma non riesco a capire come avrei eseguito un programma in grado di iscriversi e annullare l'iscrizione a un programma in esecuzione. È possibile?


Vuoi monitorare l'avanzamento all'interno delle operazioni di caricamento / risposta (durata di 10 minuti) o vuoi sapere quanti caricamenti hanno avuto luogo all'interno del ciclo "Parallel.ForEach"?
Doc Brown,

@DocBrown vedi modifica. (ultimi due paragrafi)
Robert Snyder,

1
Mi sembra che quello che vuoi sia forse un semplice programma di ricezione UDP. Puoi rilasciare i pacchetti di stato sulla rete e, se non c'è nulla lì per riceverli, nessun danno fatto.
Robert Harvey,

Risposte:


7

Ciò di cui hai bisogno è un modo di comunicare tra i tuoi programmi che non li leghi tra loro. Esistono diversi modi per farlo, potresti avere l'attività di scrivere su un file e monitorare la lettura dal file, rendere l'attività disponibile tramite WCF in modo che il monitor possa "sondare" le modifiche, utilizzare la rete ...

Per evitare di reinventare la ruota, dai un'occhiata agli obiettivi di registrazione di log4net Se dovessi implementare qualcosa di simile probabilmente userei log4net e accederei a UDP o Telnet e fare in modo che il monitor sull'altra estremità si connetta ad esso. log4net si occupa di tutto per te, incluso non generare eccezioni quando non è attivo alcun monitor.


Penso di essere d'accordo con questa risposta perché usiamo già log4net per bene ... registrazione :) Quindi questo si adatterebbe perfettamente con quello che ha. Non avevo idea che log4net potesse farlo! Grazie
Robert Snyder il

9

Dai tuoi commenti vedo che hai un database client / server disponibile e il tuo caricatore ha già una connessione e l'accesso in scrittura? Quindi sarebbe probabilmente più semplice aggiungere una tabella di "monitoraggio" o "status" al database e lasciare che l'autore del caricamento riporti i suoi progressi lì (registra ogni passaggio "interessante" lì, probabilmente i 5 passaggi che hai elencato sopra).

Per visualizzare lo stato, creare un secondo programma con GUI, che si collega al database e visualizza lo stato (ad esempio, eseguendo il polling a intervalli di 1 minuto). È possibile eseguire quel programma sul desktop locale, presupponendo che sia possibile connettersi al database da lì.

Naturalmente, quando si scrive su una tabella di stato si interferisce con le transazioni del database, è possibile utilizzare una connessione separata. Puoi anche utilizzare un meccanismo di coda messaggi come MSQM , ma potrebbe essere una soluzione sovradimensionata per il tuo caso semplice.


+1 Questo è l'approccio migliore per mantenerlo semplice e non complicare eccessivamente qualcosa che non dovrebbe essere troppo complesso.
Thomas Stringer,

3

Solo per basarsi sulla risposta di @ JDT, un modo comune per farlo è scrivere messaggi in una coda di messaggi. Ogni volta che succede qualcosa di importante nella tua applicazione, questo scrive un messaggio e lo invia alla coda dei messaggi. In genere il formato del messaggio è XML o simile. È lo scrittore di coda.

L'applicazione di monitoraggio legge (lettore di code) la coda e seleziona i messaggi e li elabora salvandoli e analizzando il messaggio rispetto ai messaggi o alle condizioni precedenti. Se viene soddisfatta una condizione, l'applicazione di monitoraggio genererà un avviso indicante un potenziale problema.

Ciò disaccoppia l'applicazione dal monitoraggio stesso in quanto sta semplicemente sparando i messaggi. Spetta all'applicazione di monitoraggio determinare in base ai messaggi correnti che è successo qualcosa di buono o di cattivo. Le code vengono utilizzate perché offrono un buon mezzo per archiviare i messaggi senza perdita.

Vuoi messaggistica centralizzata se ci sono più istanze della tua applicazione in esecuzione. Se esiste solo 1 istanza, può essere sufficiente utilizzare altri negozi come il registro eventi di Windows o un file.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.