Streaming WCF

ludogoal
Streaming WCF

Salut à tous,
J'ai une nouvelle question sur le streaming, en effet j'ai codé un téléchargement de fichier Service -> Client. Le client récupère un flux qu'il vient relire mais je ne comprends pas le fonctionnement exacte qui est mis en place (plus ou moins à mon insu). Je m'explique: côté client je récupère un objet qui contient 2 Headers et un Body (le flux qui n'est autre que le fichier en lui-même). Voici le code (côté client):

ChannelFactory factory = new ChannelFactory("epImpressionEdition");
impressionEdition = factory.CreateChannel();

SelectionsUtilisateur selectionsUtilisateur = new SelectionsUtilisateur(listCat, listDonnee);

mfile = impressionEdition.DonneFichierRapport(selectionsUtilisateur);
sourceStream = mfile.DataFile;

*************

//Spécification du répertoire où l'on souhaite placer le fichier
string uploadFolder = String.Format("{0}{1}\\{2}", AppDomain.CurrentDomain.BaseDirectory
, ConfigurationSettings.AppSettings["UploadDirectory"]
, mfile.FileName);

//destinationStream va récupérer le sourceStream qui correspond au corps du MessageFile renvoyé
//par le service, cette récupération se fait par morceau, la taille de chaque partie étant spécifiée
//par la constante bufferLen
using (destinationStream = new FileStream(uploadFolder, FileMode.Create, FileAccess.Write, FileShare.None))
{
const int bufferLen = 8192;
byte[] buffer = new byte[bufferLen];
int count = 0;
while ((count = sourceStream.Read(buffer, 0, bufferLen)) > 0)
{
destinationStream.Write(buffer, 0, count);
}
sourceStream.Close();
}
Ma question vient du fait que, si je remplace les * par :

factory.close();

j'arrive toujours à récupérer mon fichier par contre, si je mets un point d'arrêt à ce niveaux et que je ferme l'hébergeur de mon service, seules quelques boucles de relecture sont effectuées avant de remonter une erreur du type "canal de communication fermé". J'en déduis donc, à vous de me confirmer ou d'infirmer, que la mécanique interne du fonctionnement du streaming crée un canal (en gros un createChannel()) sans que je ne puisse rien y faire. Ma question est donc double, ai-je bien compris? et Comment cela fonctionne-t-il dans le détail? (appels successifs ou non, session, etc...).
Merci d'avance à tous!!!!

fredericmazue

Quote:

factory.close();
j'arrive toujours à récupérer mon fichier

Ca me parait normal. Une fois que le fichier est ouvert, il l'est. Fermer la fabrique est sans incidence sur ce point.

Quote:
par contre, si je mets un point d'arrêt à ce niveaux et que je ferme l'hébergeur de mon service, seules quelques boucles de relecture sont effectuées avant de remonter une erreur du type "canal de communication fermé". J'en déduis donc, à vous de me confirmer ou d'infirmer, que la mécanique interne du fonctionnement du streaming crée un canal (en gros un createChannel()) sans que je ne puisse rien y faire. Ma question est donc double, ai-je bien compris? et Comment cela fonctionne-t-il dans le détail? (appels successifs ou non, session, etc...).

Je ne sais pas si je comprends bien la question, ni même la réponse que je donne :) mais je vais quand même essayer de t'en donner une idée. (et essayer d'être clair...)

Le but du streaming, c'est d'économiser de la mémoire, c'est à dire ne pas charger en mémoire et transférer des grosses entités d'un seul coup.
Au lieu de cela, avec le streaming les données sont lues au fur et à mesure, à la demande.
Quand un fichier est streamé, deux descripteurs de fichiers sont ouverts, un de chaque côte. (serveur et client). Même avec ce procédé, je pense que le runtime travaille avec un buffer de faible taille. Cela parait normal pour éviter d'avoir trop d'accès disques. Donc côte client, quand tu lis une fois, sans doute plus de données que demandé sont placées dans un petit tampon par le runtime. Et tu peux faire quelques boucles de lectures, jusqu'à épuisement du tampon. A ce moment, le runtime veut lire dans le fichier, voit qu'il est fermé et émet le message d'erreur.

Enfin je pense que c'est comme ça.... Si quelqu'un connait mieux le sujet, qu'il ne se prive pas d'intervenir surtout :)

ludogoal

Quote:
Le but du streaming, c'est d'économiser de la mémoire, c'est à dire ne pas charger en mémoire et transférer des grosses entités d'un seul coup.
Au lieu de cela, avec le streaming les données sont lues au fur et à mesure, à la demande.

Sur ce point, je n'en ai jamais douté et c'est bien dans cette optique que j'ai codé mon application.

Quote:
Et tu peux faire quelques boucles de lectures, jusqu'à épuisement du tampon. A ce moment, le runtime veut lire dans le fichier, voit qu'il est fermé et émet le message d'erreur.

Donc, le fichier est lu par morceau à chaque fois que la totalité du tampon a été utilisée côté client.
Merci beaucoup pour l'info, j'ai posté sur plusieurs forum et tu es le seul qui a répondu (malgré une centaine de visites au cumule des forums) donc merci beaucoup et comme tu le dis : si quelqu'un veut apporter sa contribution, notament si vous avez expérimenté le streaming sur de gros objets (au lieu d'un fichier) vous êtes tous les bienvenus!!!!
Encore Merci!!!!!!!!!!!!!!!!!!!
:D :D :D :D :D :D
ludogoal

J'ai quand même une, enfin deux, dernières questions sur le sujet.
peut-on paramétrer et de combien est la taille par défaut de ce "petit buffer". Comment se fait le lien entre les deux descripteurs?

fredericmazue

1) je ne sais pas. Je ne pense pas. c'est contre nature de trifouiler ça je suppose.

2), je ne sais pas, et en principe on a pas à le savoir. c'est le runtime qui encapsule ça et c'est susceptible de varier d'une implémentation à l'autre, d'une version à l'autre. Donc on ne devrait pas se poser la question :)