2012-07-25 12 views
10

Ho bisogno di qualche consiglio nella codifica corretta:Buona codifica? (Multiple Message Loops)

Sto lavorando su un programma in cui vengono utilizzate più connessioni seriali. Ogni linea di comunicazione ha un controller che funziona come un livello di astrazione. Tra il controller e la porta seriale, viene inserito un protocollo per avvolgere i dati in pacchetti, pronti per il trasferimento. Il protocollo si occupa delle consegne non riuscite, del resending ecc. Per garantire che la GUI non si blocchi, ciascuna linea di connessione (protocollo e porta seriale) viene creata su un thread separato. Il controller è gestito dal thread principale, poiché ha controlli nella GUI.

Attualmente, quando creo i thread, ho scelto di creare un loop di messaggi su di essi (Application.Run()), quindi, anziché interrogare i buffer e restituire se non funziona, semplicemente invoco il thread (BeginInvoke) e utilizza il ciclo del messaggio come buffer. Attualmente funziona bene, e non ci sono ancora problemi seri.

La mia domanda è ora: è questa "buona codifica", o dovrei usare un ciclo while sul battistrada ed essere tampone di interrogazione invece ?, o una terza cosa?

Mi piacerebbe mostrare il codice, ma finora sono diverse migliaia di righe di codice, quindi per favore sii specifico se hai bisogno di vedere qualsiasi parte del codice. :)

Grazie.

risposta

4

L'utilizzo di loop di messaggi in ciascuna filettatura è perfettamente corretto; Windows è ottimizzato per questo scenario. Hai ragione di evitare il polling, ma potresti voler esaminare altri progetti basati su eventi che sono ancora più efficienti, ad esempio preparare un pacchetto per il trasferimento e chiamare SetEvent per notificare un thread che è pronto o coda di semaforo e thread-safe come Suggerisce Martin James.

+0

Non proprio, no. WM_COPYDATA va bene per la comunicazione tra processi. È inutile usarlo per comunicazioni inter-thread all'interno di un processo. È molto più semplice/semplice passare semplicemente il buffer/blob/qualsiasi oggetto tramite puntatore, ad es. lanciando il * Buffer al messaggio.lParam, PostMessage() ing e ricomincia dall'altra parte. –

+0

Le code dei messaggi di Windows sono ottimizzate per la comunicazione ai thread della GUI. Non sono ottimali per la comunicazione dai thread GUI ai thread di lavoro non-GUI. Anche una semplice coda produttore-consumatore non ottimizzata basata sul semaforo è circa quattro volte più veloce di un WMQ. Nella maggior parte delle app, le prestazioni della coda P-C normalmente non sono comunque un problema. –

+0

Sono d'accordo su entrambi i punti in realtà. Modificherò WM_COPYDATA; Non stavo pensando chiaramente. Per quanto riguarda la coda dei messaggi, si tratta di una soluzione basata su eventi generalizzata. A seconda dei requisiti della sua app, altri modelli potrebbero essere migliori. – tenfour

1

Io non sono sicuro al 100% quello che state facendo qui, ma, con un po 'di 'riempimento' non suona male :)

Quando la tua applicazione è inattivo, (nessun Comms), è La CPU usa lo 0%?

L'app è priva di sleep (0)/sleep (1) o cicli di polling simili?

Funziona con una latenza ragionevolmente bassa?

Se le risposte sono tre 'SI', si dovrebbe andare bene :)

Ci sono pochi, (molto pochi!), I casi in cui il polling per i risultati, ecc è una buona idea, (ad es. Quando la frequenza degli eventi nei thread è così alta che la segnalazione di ogni evento progressivo alla GUI lo travolgerebbe), ma per lo più, è solo un design scadente.

+0

Lo scopo di questo programma è quello di controllare 1-4 (finora) riquadri, ciascuno contenente un Arduino. Ogni Arduino è collegato agli I/O digitali di un sistema di simulazione. I sistemi di simulazione paralleli hanno bisogno di un box pr. simulatore. I simulatori fanno parte della ricerca e sviluppo dell'azienda in cui lavoro. Il programma Windows ha la possibilità di riprogrammare la piedinatura Arduino in fase di runtime, insieme alla lettura/scrittura degli stati alto/basso dei pin. – Anders

+0

Triple YES da qui .. Ho provato a cambiare il codice per fare il polling del buffer, con thread.yields se nessun dato, e questo ha reso il programma privo di un po ', quindi suppongo che stia bene con i loop del messaggio :) – Anders

+0

Bene, Potrei aver usato code leggermente diverse ecc, ma se l'app è abbastanza efficiente, risponde rapidamente e non si blocca, a chi importa :)) –