2011-08-24 12 views
6

Attualmente sto testando una libreria di rete C# gestita che ho scritto e mi sono imbattuto in un problema occasionale. Questo problema si manifesta come un blocco di 5000 ms molto coerente (sempre all'interno di 30ms) su networkstream.write() per circa l'1% di tutte le operazioni di invio. Questo è in un ambiente di test, tutto in esecuzione localmente, utilizzando la stessa esatta dimensione del pacchetto (2 MB) ogni volta. Sul lato client ho continuamente scrivo quanto segue per un NetworkStream collegato:Networkstream.Write() Problema di blocco

tcpClientNetworkStream.Write(headerBytes, 0, headerBytes.Length); 
tcpClientNetworkStream.Write(dataBytes, 0, dataBytes.Length); 

e sul lato server che uso un asincrono leggere in attesa dei dati. Una volta visualizzati i dati, utilizzo un ciclo while su tcpClientNetworkStream.DataAvailable fino a quando non sono stati ricevuti tutti i dati.

Sono consapevole del fatto che networkstream.write() può bloccare se i buffer sono pieni ma se questo è il problema non riesco a pensare a un modo più rapido di eliminarli dal server (le dimensioni del buffer di invio e ricezione sono predefinite a 8192 byte). Il fatto che il blocco sia così consistente sembra molto strano. Il mio primo pensiero fu probabilmente una qualche forma di Thread.Sleep ma fare una ricerca di un progetto completo non ne mostra nessuno. Se qualcuno potesse contribuire a far luce su questo tema che sarebbe molto apprezzato.

Marc

modifica per aggiungere: Un hack che sembra rendere il problema andare via è la seguente (anche se v'è una performance associata colpito a causa della BlockCopy):

byte[] bytesToSend = new byte[headerBytes.Length + dataBytes.Length]; 
Buffer.BlockCopy(headerBytes, 0, bytesToSend, 0, headerBytes.Length); 
Buffer.BlockCopy(dataBytes, 0, bytesToSend, headerBytes.Length, dataBytes.Length); 
tcpClientNetworkStream.Write(bytesToSend, 0, bytesToSend.Length); 

Modifica per ADD2 : Ho anche riprodotto il problema utilizzando due scritture asincrone con un segnale di thread tra i due. Al momento l'unica soluzione che ho è la singola operazione di scrittura come nella modifica sopra.

modifica to add3: Ok, segue un'altra possibile correzione. Sono ancora interessato a sapere perché i successivi scrivono occasionalmente 'blocchi' nel modo in cui lo fa.

BufferedStream sendStream = new BufferedStream(tcpClientNetworkStream); 
sendStream.Write(bytesToSend, 0, bytesToSend.Length); 
sendStream.Write(packet.PacketData, 0, packet.PacketData.Length); 
sendStream.Flush(); 

modifica per ADD4: Dopo ulteriori vasta testare la soluzione in 'modifica per ADD3' non rende il problema andare via, solo riduce l'insorgenza a circa 0,1% di mandate. Molto meglio ma tutt'altro che risolto. Sostituirò la lettura asincrona con una lettura di blocco successiva per vedere se lo ordina, come suggerito da PaulF.

+0

Invia altro codice per favore, come da dove arrivano i dataByte? È tamponato da qualche parte? – EKS

+0

Ho passato un oggetto pacchetto ad un metodo SendPacket() che contiene i metodi NetworkStream.Write() sopra. Una volta che questo oggetto pacchetto viene creato al di fuori di SendPacket() contiene matrici di byte sia per 'headerBytes' che per 'dataBytes'. – MarcF

+0

Sono curioso di sapere se il problema persiste se si utilizzano letture sincrone (bloccanti) sul lato server. – PaulF

risposta

2

Ok, nessuna risposta specifica a questa domanda, quindi farò del mio meglio per dare una piccola conclusione. La mia ipotesi migliore è che questo problema è stato originariamente causato dal fatto che stavo riempiendo il buffer tcp più velocemente di quanto lo stavo ripulendo. Se il buffer è pieno, c'è un tempo di attesa sconosciuto prima di tentare di aggiungere altri dati. Questo problema potrebbe essere più evidente quando si inviano e si ricevono dati all'interno della stessa macchina. È importante ricordare che la dimensione del buffer di lettura predefinita in .net è di soli 8192 byte, quindi se si scrive in blocchi molto più grandi, si potrebbe considerare di aumentare questa dimensione del buffer di lettura a qualcosa di più grande come 512000 byte. Tuttavia questo di per sé causa altri problemi a causa dell'heap di oggetti di grandi dimensioni, ecc. Ma è potenzialmente una discussione su una domanda diversa.

Problemi correlati