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.
Invia altro codice per favore, come da dove arrivano i dataByte? È tamponato da qualche parte? – EKS
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
Sono curioso di sapere se il problema persiste se si utilizzano letture sincrone (bloccanti) sul lato server. – PaulF