Question

J'ai un serveur TCP écrit en C # qui traite les données POST qui lui sont envoyés. Actuellement, il fonctionne très bien à moins qu'une grande quantité de données (par exemple supérieure à 1 Go) est envoyé alors il est à court de mémoire (je stocke tout dans la mémoire comme un tableau d'octets (avec un intermédiaire d'une liste DTO)). Pour de gros fichiers maintenant je ruisseler sur le disque et passe ensuite le nom du fichier dans l'intention de celui-ci depuis le disque dur.

À l'heure actuelle toutes mes routines sont écrites pour attendre des tableaux d'octets qui, avec le recul, était un peu courte vue. Si je convertir juste le bytearray à un MemoryStream il va doubler l'utilisation de la mémoire? Je pense que réécrivant mon code pour travailler sur un MemoryStream me permettra de réutiliser quand je lis un flux à partir du disque?

Désolé pour les questions stupides, je ne suis jamais sûr quand c # prend une copie des données ou lorsqu'il prend une référence.

Était-ce utile?

La solution

Si vous passez un byte[] dans un MemoryStream, il copie les données initialement (dans le constructeur), mais aussi longtemps que vous relâchez le byte[] il peut être garbage collection. Intrinsèquement il n'y a pas de « doubler » (surtout si vous pouvez définir la taille correcte pour commencer, et écrire directement à la Stream plutôt que le byte[]).

Je dire tout à fait passer à Stream (mais uniquement Utilisation Stream dans l'API - rien de spécifique de Moer, votre code ne consommant pas besoin de savoir quel type). Plus important encore, vous pouvez choisir d'utiliser le NetworkStream (pour lire directement à partir de la prise) ou FileStream (si vous voulez tampon sur le disque), ou MemoryStream si vous voulez tampon en cours. Vous devrez également vous assurer que vous avez bien lu volume de données via le code en fonction flux. blocs iterator (de yield return) peuvent être très utiles ici, tout comme les méthodes de Enumerable LINQ (sauf pour OrderBy, GroupBy, etc, qui tampon).

Ni le passage d'un byte[] ni passer un Stream fait quoi que ce soit pour obtenir copie, car ils sont types-référence -. La seule chose copiée est la référence (4 ou 8 octets, selon x86 / x64)

Autres conseils

A MemoryStream est juste une enveloppe de flux autour d'un tableau d'octets, de sorte que vous ne serez pas gagner quoi que ce soit en l'utilisant.

Ce que vous devez faire (pour des fichiers volumineux au moins) est ouvert un FileStream et de vidage vos données dans ce. À un niveau plus bas que vous devez lire des octets X de votre connexion, puis écrire que immédiatement à votre flux de fichiers. De cette façon, vous ne serez pas tirer dans un concert complet en mémoire mais seulement quelques octets à la fois.

Si oui ou non ce sera facile à faire dépend de la façon dont votre serveur TCP est codé.

Comme un octet est un type de valeur, si vous passez à une fonction sans le mot-clé ref vous traiterez une copie à chaque fois. Si vous passez avec le mot-clé ref, il va prendre une référence au tableau d'octets d'origine.

A MemoryStream est un type de référence, il ne sera pas copier les données, mais vous passez autour d'une référence à ces données, de sorte que votre utilisation de la mémoire ne doublera pas sur l'utilisation que.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top