2010-04-13 26 views
9

Sto usando .NET 3.5 e sto cercando di avvolgere la mia mente attorno a un problema (non essendo un esperto di threading supremo sopportare con me).C# Comunicazione tra thread

Ho un servizio Windows che ha un processo molto intenso che è sempre in esecuzione, ho messo questo processo su un thread separato in modo che il thread principale del mio servizio sia in grado di gestire le operazioni operative, ovvero cicli di controllo del servizio, gestione della configurazione modifiche, ecc, ecc

sto iniziando il filo attraverso il tipico ThreadStart a un metodo che prende il processo fuori - lo chiamano workerthread.

Su questo workthread invio i dati a un altro server, come previsto, il server si riavvia di tanto in tanto e la connessione è persa e devo ristabilire la connessione (la notifica della perdita di connessione tramite un evento mi viene segnalata). Da qui faccio la mia riconnessione logica e sono di nuovo in esecuzione, tuttavia quello che ho iniziato a notare è che stavo creando questo thread di lavoro più e più volte ogni volta (non quello che voglio).

Ora potevo uccidere il workerthread quando perdo la connessione e iniziare uno nuovo, ma questo mi sembra uno spreco di risorse.

Quello che voglio davvero fare, è maresciallo la chiamata (vale a dire, il mio thread metodo start) torna al thread che è ancora in memoria, anche se non fare nulla.

Si prega di inviare qualsiasi esempio o documenti che avete che sarebbe utile.

Grazie.

+0

Puoi pubblicare un po 'del tuo codice? – ChaosPandion

+1

+1 Bella domanda, la gente sembra non votare più per le buone domande ... –

risposta

1

Vorrei uccidere (ma terminare con grazia se possibile) il thread di lavoro comunque. Tutto viene raccolto dai rifiuti e puoi iniziare da zero.

Con quale frequenza si verifica il riavvio del server? Se capita spesso che le risorse siano un problema, probabilmente sta succedendo troppo spesso.

+0

Nota: come sottolinea dthorpe, non dovresti semplicemente scaricare la discussione. Prova a ripulire il maggior numero possibile di risorse prima di scaricare il thread nel solito modo –

1

È possibile utilizzare il modello Singleton. Nel tuo caso, rendi la connessione un oggetto statico. Entrambi i thread possono accedere all'oggetto, il che significa costruirlo e usarlo.

Il filo principale potrebbe costruirlo quando necessario, e l'accesso thread di lavoro ogni volta che è disponibile.

1

chiamare il metodo utilizzando ThreadPool.QueueUserWorkItem invece. Questo metodo prende una discussione dal pool di thread e avvia un metodo. Sembra essere l'ideale per il compito di avviare un metodo su un altro thread.

Inoltre, quando si dice "ThreadStart tipico" vuoi dire che si sta creando e di iniziare una nuova Thread con un parametro ThreadStart, o si sta creando un ThreadStart e chiamando Invoke su di esso?

+0

Ecco come faccio nel mio servizio Windows, ma eseguo più attività in background. –

+0

@Robert: stai dicendo che 'QueueUserWorkItem' è eccessivo per un'attività occasionale occasionale come questa? Probabilmente è vero, ma ho l'abitudine di usarlo perché so che non devo preoccuparmi di eliminare il thread in questione. – MusiGenesis

+0

I thread QueueUserWorkItem devono essere utilizzati solo per operazioni di breve durata. L'utilizzo dei thread del threadpool per le operazioni a esecuzione prolungata può esaurire il threadpool (numero finito di thread) e causare l'attesa di altri client di QueueUserWorkItem nel processo prima che un thread del threadpool diventi disponibile. – dthorpe

1

avete considerato un BackgroundWorker?

Da quello che ho capito, hai solo un singolo thread che sta funzionando, a meno che non si presenti il ​​caso in cui devi elaborare cancel.

3

Evitare di eliminare il thread di lavoro. Quando si uccide forzatamente un thread Win32, non tutte le risorse vengono completamente ripristinate. Credo che lo spazio di indirizzi virtuale riservato (o è la pagina radice?) Per lo stack di thread non viene ripristinato quando viene ucciso un thread Win32. Potrebbe non essere molto, ma in un lungo processo di servizio del server, si sommerà nel tempo e alla fine abbatterà il servizio.

Se il thread è autorizzato a uscire da threadproc per terminare normalmente, tutte le risorse vengono ripristinate.

Se il thread in background verrà eseguito continuamente (non in modalità di sospensione), è possibile utilizzare solo un flag booleano globale per comunicare lo stato tra il thread principale e il thread in background. Finché il thread in background controlla periodicamente questa bandiera globale. Se il flag è impostato, il thread può chiudersi automaticamente e uscire. Non c'è bisogno di bloccare la semantica se il thread principale è l'unico writer e il thread in background legge solo il valore del flag.

Quando il thread in background perde la connessione al server a cui invia i dati, perché non esegue la riconnessione autonomamente? Non mi è chiaro perché il thread principale debba abbattere il thread in background per avviarne un altro.

1

Il BackgroundWorker è un po 'più lento rispetto all'utilizzo di thread semplici, ma ha la possibilità di supportare il metodo CancelAsync.
Fondamentalmente, BackgroundWorker è un wrapper attorno a un thread di lavoro con alcune opzioni ed eventi aggiuntivi.

Il metodo CancelAsync funziona solo quando è impostato WorkerSupportsCancellation.
Quando viene chiamato CancelAsync, viene impostato CancellationPending.
Il thread di lavoro deve controllare periodicamente lo CancellationPending per vedere se è necessario uscire prematuramente.

- jeroen