Upload avec IIS : Fichier fermé

Le
David
Bonjour,

J'ai un bout de code qui me permet de faire de l'upload avec un composant
upload ASP.Net.
Le code fonctionne très bien avec le serveur interne de VS.Net 2005, par
contre avec IIS 5 il me génère un IODisposedObject lorsque j'essaye de lire
le fichier source.

Voici le code :
// Flux d'écriture du fichier sur le serveur
FileStream fs = new FileStream(this.p_filesNames[i],
FileMode.OpenOrCreate);

// Flux de lecture du fichier
BinaryReader br = new BinaryReader(file.InputStream);

try
{
// Tant qu'on a pas tout lu et qu'on ne doit pas stopper
while (br.BaseStream.Length - br.BaseStream.Position > 0 &&
!this.p_stopUpload)
{

// S'il y a moins d'octet a récupérér que la taille du tampon
if (br.BaseStream.Length - br.BaseStream.Position < bufferSize)
{
bufferSize = (int)(br.BaseStream.Length -
br.BaseStream.Position);
}

br.Read(buffer, 0, bufferSize); // lecture => il plante ici
!!!!!
fs.Write(buffer, 0, bufferSize); // écriture
this.p_totalUploaded += bufferSize;
this.p_partialUploaded = br.BaseStream.Position;
}
}
finally
{
// Fermeture des flux
br.Close();
fs.Close();
}

Et je peux vous assurer que le fichier que je veux uploader n'est pas ouvert
ou utilisé par quelque chose.
Par contre, j'ai remarqué que ça fonctionne pour des fichier < 64 Ko !!
Encore une fois, pour des gros fichiers, ça fonctionne avec le petit serveur
interne.
Quelle est dans IIS l'option qui déconne ?

Merci pour votre aide.
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 3
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Gilles TOURREAU
Le #12182521
Le Fri, 22 Jun 2007 17:39:03 +0200, David

Bonjour,

J'ai un bout de code qui me permet de faire de l'upload avec un composant
upload ASP.Net.
Le code fonctionne très bien avec le serveur interne de VS.Net 2005, par
contre avec IIS 5 il me génère un IODisposedObject lorsque j'essaye de
lire
le fichier source.

Voici le code :
// Flux d'écriture du fichier sur le serveur
FileStream fs = new FileStream(this.p_filesNames[i],
FileMode.OpenOrCreate);

// Flux de lecture du fichier
BinaryReader br = new BinaryReader(file.InputStream);
try
{
// Tant qu'on a pas tout lu et qu'on ne doit pas stopper
while (br.BaseStream.Length - br.BaseStream.Position > 0 &&
!this.p_stopUpload)
{

// S'il y a moins d'octet a récupérér que la taille du
tampon
if (br.BaseStream.Length - br.BaseStream.Position <
bufferSize)
{
bufferSize = (int)(br.BaseStream.Length -
br.BaseStream.Position);
}

br.Read(buffer, 0, bufferSize); // lecture => il plante ici
!!!!!
fs.Write(buffer, 0, bufferSize); // écriture
this.p_totalUploaded += bufferSize;
this.p_partialUploaded = br.BaseStream.Position;
}
}
finally
{
// Fermeture des flux
br.Close();
fs.Close();
}

Et je peux vous assurer que le fichier que je veux uploader n'est pas
ouvert
ou utilisé par quelque chose.
Par contre, j'ai remarqué que ça fonctionne pour des fichier < 64 Ko !!
Encore une fois, pour des gros fichiers, ça fonctionne avec le petit
serveur
interne.
Quelle est dans IIS l'option qui déconne ?

Merci pour votre aide.



Peux-tu poster le code concernant l'utilisation de la variable : file

Cordialement

--
Gilles TOURREAU


S.A.R.L. P.O.S
Le spécialiste en motoculture depuis + de 30 ans !
http://www.pos.fr
David
Le #12182511
En fait, je boucle sur plusieurs fichiers à uploader :
HttpFileCollection p_files = Request.Files;
for (int i = 0; i < this.p_files.Count; i++)
{
HttpPostedFile file = this.p_files[i];
... Le code vu plus bas ...
}

--
David

"Gilles TOURREAU" a écrit :

Le Fri, 22 Jun 2007 17:39:03 +0200, David

> Bonjour,
>
> J'ai un bout de code qui me permet de faire de l'upload avec un composant
> upload ASP.Net.
> Le code fonctionne très bien avec le serveur interne de VS.Net 2005, par
> contre avec IIS 5 il me génère un IODisposedObject lorsque j'essaye de
> lire
> le fichier source.
>
> Voici le code :
> // Flux d'écriture du fichier sur le serveur
> FileStream fs = new FileStream(this.p_filesNames[i],
> FileMode.OpenOrCreate);
>
> // Flux de lecture du fichier
> BinaryReader br = new BinaryReader(file.InputStream);
> try
> {
> // Tant qu'on a pas tout lu et qu'on ne doit pas stopper
> while (br.BaseStream.Length - br.BaseStream.Position > 0 &&
> !this.p_stopUpload)
> {
>
> // S'il y a moins d'octet a récupérér que la taille du
> tampon
> if (br.BaseStream.Length - br.BaseStream.Position <
> bufferSize)
> {
> bufferSize = (int)(br.BaseStream.Length -
> br.BaseStream.Position);
> }
>
> br.Read(buffer, 0, bufferSize); // lecture => il plante ici
> !!!!!
> fs.Write(buffer, 0, bufferSize); // écriture
> this.p_totalUploaded += bufferSize;
> this.p_partialUploaded = br.BaseStream.Position;
> }
> }
> finally
> {
> // Fermeture des flux
> br.Close();
> fs.Close();
> }
>
> Et je peux vous assurer que le fichier que je veux uploader n'est pas
> ouvert
> ou utilisé par quelque chose.
> Par contre, j'ai remarqué que ça fonctionne pour des fichier < 64 Ko !!
> Encore une fois, pour des gros fichiers, ça fonctionne avec le petit
> serveur
> interne.
> Quelle est dans IIS l'option qui déconne ?
>
> Merci pour votre aide.

Peux-tu poster le code concernant l'utilisation de la variable : file

Cordialement

--
Gilles TOURREAU


S.A.R.L. P.O.S
Le spécialiste en motoculture depuis + de 30 ans !
http://www.pos.fr



Gilles TOURREAU
Le #12182481
Le Fri, 22 Jun 2007 18:23:05 +0200, David

En fait, je boucle sur plusieurs fichiers à uploader :
HttpFileCollection p_files = Request.Files;
for (int i = 0; i < this.p_files.Count; i++)
{
HttpPostedFile file = this.p_files[i];
... Le code vu plus bas ...
}

--
David

"Gilles TOURREAU" a écrit :

Le Fri, 22 Jun 2007 17:39:03 +0200, David

> Bonjour,
>
> J'ai un bout de code qui me permet de faire de l'upload avec un
composant
> upload ASP.Net.
> Le code fonctionne très bien avec le serveur interne de VS.Net 2005,
par
> contre avec IIS 5 il me génère un IODisposedObject lorsque j'essaye de
> lire
> le fichier source.
>
> Voici le code :
> // Flux d'écriture du fichier sur le serveur
> FileStream fs = new FileStream(this.p_filesNames[i],
> FileMode.OpenOrCreate);
>
> // Flux de lecture du fichier
> BinaryReader br = new BinaryReader(file.InputStream);
> try
> {
> // Tant qu'on a pas tout lu et qu'on ne doit pas stopper
> while (br.BaseStream.Length - br.BaseStream.Position > 0
&&
> !this.p_stopUpload)
> {
>
> // S'il y a moins d'octet a récupérér que la taille du
> tampon
> if (br.BaseStream.Length - br.BaseStream.Position <
> bufferSize)
> {
> bufferSize = (int)(br.BaseStream.Length -
> br.BaseStream.Position);
> }
>
> br.Read(buffer, 0, bufferSize); // lecture => il plante
ici
> !!!!!
> fs.Write(buffer, 0, bufferSize); // écriture
> this.p_totalUploaded += bufferSize;
> this.p_partialUploaded = br.BaseStream.Position;
> }
> }
> finally
> {
> // Fermeture des flux
> br.Close();
> fs.Close();
> }
>
> Et je peux vous assurer que le fichier que je veux uploader n'est pas
> ouvert
> ou utilisé par quelque chose.
> Par contre, j'ai remarqué que ça fonctionne pour des fichier < 64 Ko
!!
> Encore une fois, pour des gros fichiers, ça fonctionne avec le petit
> serveur
> interne.
> Quelle est dans IIS l'option qui déconne ?
>
> Merci pour votre aide.

Peux-tu poster le code concernant l'utilisation de la variable : file

Cordialement

--
Gilles TOURREAU


S.A.R.L. P.O.S
Le spécialiste en motoculture depuis + de 30 ans !
http://www.pos.fr






Je vois pas où il y aurait un problème...
Cette exception est déclenché uniquement dans le cas ou vous appelez la
méthode Close() ou Dispose() du BinaryReader et après un Read().

Essayez cependant cette solution qui est bien meilleur que le try/finally :

using (FileStream fs = new FileStream(this.p_filesNames[i],
FileMode.OpenOrCreate))
{
using (BinaryReader br = new BinaryReader(file.InputStream))
{
//... Le code

//Inutile de faire un close à la fin des using, car la méthode
Dispose est automatiquement libéré...
}
}

Cordialement


--
Gilles TOURREAU


S.A.R.L. P.O.S
Le spécialiste en motoculture depuis + de 30 ans !
http://www.pos.fr
Gilles TOURREAU
Le #12182451
Le Fri, 22 Jun 2007 20:00:41 +0200, Gilles TOURREAU

Le Fri, 22 Jun 2007 18:23:05 +0200, David

En fait, je boucle sur plusieurs fichiers à uploader :
HttpFileCollection p_files = Request.Files;
for (int i = 0; i < this.p_files.Count; i++)
{
HttpPostedFile file = this.p_files[i];
... Le code vu plus bas ...
}

--
David

"Gilles TOURREAU" a écrit :

Le Fri, 22 Jun 2007 17:39:03 +0200, David

> Bonjour,
>
> J'ai un bout de code qui me permet de faire de l'upload avec un
composant
> upload ASP.Net.
> Le code fonctionne très bien avec le serveur interne de VS.Net 2005,
par
> contre avec IIS 5 il me génère un IODisposedObject lorsque j'essaye
de
> lire
> le fichier source.
>
> Voici le code :
> // Flux d'écriture du fichier sur le serveur
> FileStream fs = new FileStream(this.p_filesNames[i],
> FileMode.OpenOrCreate);
>
> // Flux de lecture du fichier
> BinaryReader br = new BinaryReader(file.InputStream);
> try
> {
> // Tant qu'on a pas tout lu et qu'on ne doit pas stopper
> while (br.BaseStream.Length - br.BaseStream.Position > 0
&&
> !this.p_stopUpload)
> {
>
> // S'il y a moins d'octet a récupérér que la taille du
> tampon
> if (br.BaseStream.Length - br.BaseStream.Position <
> bufferSize)
> {
> bufferSize = (int)(br.BaseStream.Length -
> br.BaseStream.Position);
> }
>
> br.Read(buffer, 0, bufferSize); // lecture => il
plante ici
> !!!!!
> fs.Write(buffer, 0, bufferSize); // écriture
> this.p_totalUploaded += bufferSize;
> this.p_partialUploaded = br.BaseStream.Position;
> }
> }
> finally
> {
> // Fermeture des flux
> br.Close();
> fs.Close();
> }
>
> Et je peux vous assurer que le fichier que je veux uploader n'est pas
> ouvert
> ou utilisé par quelque chose.
> Par contre, j'ai remarqué que ça fonctionne pour des fichier < 64 Ko
!!
> Encore une fois, pour des gros fichiers, ça fonctionne avec le petit
> serveur
> interne.
> Quelle est dans IIS l'option qui déconne ?
>
> Merci pour votre aide.

Peux-tu poster le code concernant l'utilisation de la variable : file

Cordialement

--
Gilles TOURREAU


S.A.R.L. P.O.S
Le spécialiste en motoculture depuis + de 30 ans !
http://www.pos.fr






Je vois pas où il y aurait un problème...
Cette exception est déclenché uniquement dans le cas ou vous appelez la
méthode Close() ou Dispose() du BinaryReader et après un Read().

Essayez cependant cette solution qui est bien meilleur que le
try/finally :

using (FileStream fs = new FileStream(this.p_filesNames[i],
FileMode.OpenOrCreate))
{
using (BinaryReader br = new BinaryReader(file.InputStream))
{
//... Le code

//Inutile de faire un close à la fin des using, car la méthode
Dispose est automatiquement libéré...
}
}

Cordialement





Je viens de remarquer un truc interessant sur un de mes sites ASP...
Quand le site "plante" (evenement Application_Error déclenché dans
Global.asax), .NET libère toutes les ressources de toutes les demandes en
cours en appellant la méthode Dispose() de tous les objets...

Peut-être un début de piste pour toi :
- Est-ce que ton site internet sur le IIS est utilisé par plusieurs
utilisateurs en même temps ?
- Si c'est le cas, cela veut dire qu'au moment du plantage, .NET appelle
la méthode Dispose() de ton file.InputStream....

Cordialement

--
Gilles TOURREAU


S.A.R.L. P.O.S
Le spécialiste en motoculture depuis + de 30 ans !
http://www.pos.fr
David
Le #12182441
Merci pour les pistes, mais hélas, j'ai réessayé avec les using et rien y
fait, même si en effet c'est plus propre.
Je pense manifestement à quelque chose comme des paramètres IIS ou à mon
web.config ?

Ce que je ne comprends pas, c'est que ça fonctionne bien avec le serveur
interne...

L'exception exact est :
ObjectDisposedException : Imposible d'accéder à un fichier fermé.

Pourquoi serait-il fermé ?
Il faut que je l'ouvre autrement ?
N'y aurait-il pas un autre bout de code avec des objets différents qui
pourrait faire l'affaire ?

Merci.


"Gilles TOURREAU" a écrit :

Le Fri, 22 Jun 2007 20:00:41 +0200, Gilles TOURREAU

> Le Fri, 22 Jun 2007 18:23:05 +0200, David
> >
>> En fait, je boucle sur plusieurs fichiers à uploader :
>> HttpFileCollection p_files = Request.Files;
>> for (int i = 0; i < this.p_files.Count; i++)
>> {
>> HttpPostedFile file = this.p_files[i];
>> ... Le code vu plus bas ...
>> }
>>
>> --
>> David
>>
>> "Gilles TOURREAU" a écrit :
>>
>>> Le Fri, 22 Jun 2007 17:39:03 +0200, David
>>> >>>
>>> > Bonjour,
>>> >
>>> > J'ai un bout de code qui me permet de faire de l'upload avec un
>>> composant
>>> > upload ASP.Net.
>>> > Le code fonctionne très bien avec le serveur interne de VS.Net 2005,
>>> par
>>> > contre avec IIS 5 il me génère un IODisposedObject lorsque j'essaye
>>> de
>>> > lire
>>> > le fichier source.
>>> >
>>> > Voici le code :
>>> > // Flux d'écriture du fichier sur le serveur
>>> > FileStream fs = new FileStream(this.p_filesNames[i],
>>> > FileMode.OpenOrCreate);
>>> >
>>> > // Flux de lecture du fichier
>>> > BinaryReader br = new BinaryReader(file.InputStream);
>>> > try
>>> > {
>>> > // Tant qu'on a pas tout lu et qu'on ne doit pas stopper
>>> > while (br.BaseStream.Length - br.BaseStream.Position > 0
>>> &&
>>> > !this.p_stopUpload)
>>> > {
>>> >
>>> > // S'il y a moins d'octet a récupérér que la taille du
>>> > tampon
>>> > if (br.BaseStream.Length - br.BaseStream.Position <
>>> > bufferSize)
>>> > {
>>> > bufferSize = (int)(br.BaseStream.Length -
>>> > br.BaseStream.Position);
>>> > }
>>> >
>>> > br.Read(buffer, 0, bufferSize); // lecture => il
>>> plante ici
>>> > !!!!!
>>> > fs.Write(buffer, 0, bufferSize); // écriture
>>> > this.p_totalUploaded += bufferSize;
>>> > this.p_partialUploaded = br.BaseStream.Position;
>>> > }
>>> > }
>>> > finally
>>> > {
>>> > // Fermeture des flux
>>> > br.Close();
>>> > fs.Close();
>>> > }
>>> >
>>> > Et je peux vous assurer que le fichier que je veux uploader n'est pas
>>> > ouvert
>>> > ou utilisé par quelque chose.
>>> > Par contre, j'ai remarqué que ça fonctionne pour des fichier < 64 Ko
>>> !!
>>> > Encore une fois, pour des gros fichiers, ça fonctionne avec le petit
>>> > serveur
>>> > interne.
>>> > Quelle est dans IIS l'option qui déconne ?
>>> >
>>> > Merci pour votre aide.
>>>
>>> Peux-tu poster le code concernant l'utilisation de la variable : file
>>>
>>> Cordialement
>>>
>>> --
>>> Gilles TOURREAU
>>>
>>>
>>> S.A.R.L. P.O.S
>>> Le spécialiste en motoculture depuis + de 30 ans !
>>> http://www.pos.fr
>>>
>
> Je vois pas où il y aurait un problème...
> Cette exception est déclenché uniquement dans le cas ou vous appelez la
> méthode Close() ou Dispose() du BinaryReader et après un Read().
>
> Essayez cependant cette solution qui est bien meilleur que le
> try/finally :
>
> using (FileStream fs = new FileStream(this.p_filesNames[i],
> FileMode.OpenOrCreate))
> {
> using (BinaryReader br = new BinaryReader(file.InputStream))
> {
> //... Le code
>
> //Inutile de faire un close à la fin des using, car la méthode
> Dispose est automatiquement libéré...
> }
> }
>
> Cordialement
>
>

Je viens de remarquer un truc interessant sur un de mes sites ASP...
Quand le site "plante" (evenement Application_Error déclenché dans
Global.asax), .NET libère toutes les ressources de toutes les demandes en
cours en appellant la méthode Dispose() de tous les objets...

Peut-être un début de piste pour toi :
- Est-ce que ton site internet sur le IIS est utilisé par plusieurs
utilisateurs en même temps ?
- Si c'est le cas, cela veut dire qu'au moment du plantage, .NET appelle
la méthode Dispose() de ton file.InputStream....

Cordialement

--
Gilles TOURREAU


S.A.R.L. P.O.S
Le spécialiste en motoculture depuis + de 30 ans !
http://www.pos.fr



David
Le #12182431
Pour info, je suis seul à utiliser le site (en dev actuellement) et je suis
donc en local également.



"Gilles TOURREAU" a écrit :

Le Fri, 22 Jun 2007 20:00:41 +0200, Gilles TOURREAU

> Le Fri, 22 Jun 2007 18:23:05 +0200, David
> >
>> En fait, je boucle sur plusieurs fichiers à uploader :
>> HttpFileCollection p_files = Request.Files;
>> for (int i = 0; i < this.p_files.Count; i++)
>> {
>> HttpPostedFile file = this.p_files[i];
>> ... Le code vu plus bas ...
>> }
>>
>> --
>> David
>>
>> "Gilles TOURREAU" a écrit :
>>
>>> Le Fri, 22 Jun 2007 17:39:03 +0200, David
>>> >>>
>>> > Bonjour,
>>> >
>>> > J'ai un bout de code qui me permet de faire de l'upload avec un
>>> composant
>>> > upload ASP.Net.
>>> > Le code fonctionne très bien avec le serveur interne de VS.Net 2005,
>>> par
>>> > contre avec IIS 5 il me génère un IODisposedObject lorsque j'essaye
>>> de
>>> > lire
>>> > le fichier source.
>>> >
>>> > Voici le code :
>>> > // Flux d'écriture du fichier sur le serveur
>>> > FileStream fs = new FileStream(this.p_filesNames[i],
>>> > FileMode.OpenOrCreate);
>>> >
>>> > // Flux de lecture du fichier
>>> > BinaryReader br = new BinaryReader(file.InputStream);
>>> > try
>>> > {
>>> > // Tant qu'on a pas tout lu et qu'on ne doit pas stopper
>>> > while (br.BaseStream.Length - br.BaseStream.Position > 0
>>> &&
>>> > !this.p_stopUpload)
>>> > {
>>> >
>>> > // S'il y a moins d'octet a récupérér que la taille du
>>> > tampon
>>> > if (br.BaseStream.Length - br.BaseStream.Position <
>>> > bufferSize)
>>> > {
>>> > bufferSize = (int)(br.BaseStream.Length -
>>> > br.BaseStream.Position);
>>> > }
>>> >
>>> > br.Read(buffer, 0, bufferSize); // lecture => il
>>> plante ici
>>> > !!!!!
>>> > fs.Write(buffer, 0, bufferSize); // écriture
>>> > this.p_totalUploaded += bufferSize;
>>> > this.p_partialUploaded = br.BaseStream.Position;
>>> > }
>>> > }
>>> > finally
>>> > {
>>> > // Fermeture des flux
>>> > br.Close();
>>> > fs.Close();
>>> > }
>>> >
>>> > Et je peux vous assurer que le fichier que je veux uploader n'est pas
>>> > ouvert
>>> > ou utilisé par quelque chose.
>>> > Par contre, j'ai remarqué que ça fonctionne pour des fichier < 64 Ko
>>> !!
>>> > Encore une fois, pour des gros fichiers, ça fonctionne avec le petit
>>> > serveur
>>> > interne.
>>> > Quelle est dans IIS l'option qui déconne ?
>>> >
>>> > Merci pour votre aide.
>>>
>>> Peux-tu poster le code concernant l'utilisation de la variable : file
>>>
>>> Cordialement
>>>
>>> --
>>> Gilles TOURREAU
>>>
>>>
>>> S.A.R.L. P.O.S
>>> Le spécialiste en motoculture depuis + de 30 ans !
>>> http://www.pos.fr
>>>
>
> Je vois pas où il y aurait un problème...
> Cette exception est déclenché uniquement dans le cas ou vous appelez la
> méthode Close() ou Dispose() du BinaryReader et après un Read().
>
> Essayez cependant cette solution qui est bien meilleur que le
> try/finally :
>
> using (FileStream fs = new FileStream(this.p_filesNames[i],
> FileMode.OpenOrCreate))
> {
> using (BinaryReader br = new BinaryReader(file.InputStream))
> {
> //... Le code
>
> //Inutile de faire un close à la fin des using, car la méthode
> Dispose est automatiquement libéré...
> }
> }
>
> Cordialement
>
>

Je viens de remarquer un truc interessant sur un de mes sites ASP...
Quand le site "plante" (evenement Application_Error déclenché dans
Global.asax), .NET libère toutes les ressources de toutes les demandes en
cours en appellant la méthode Dispose() de tous les objets...

Peut-être un début de piste pour toi :
- Est-ce que ton site internet sur le IIS est utilisé par plusieurs
utilisateurs en même temps ?
- Si c'est le cas, cela veut dire qu'au moment du plantage, .NET appelle
la méthode Dispose() de ton file.InputStream....

Cordialement

--
Gilles TOURREAU


S.A.R.L. P.O.S
Le spécialiste en motoculture depuis + de 30 ans !
http://www.pos.fr



David
Le #12182421
En fait, je viens de faire des tests :
Si j'exécute le code directement sur le OnClick d'un bouton, ça fonctionne
nickel même avec IIS !
Par contre, dans mon cas, je lance le traitement dans un thread.
Et apparemment, c'est de là que vient le pb.

En fait, je récupère la liste des fichiers dans un HttpFileCollection.
J'instancie une classe (Uploading) en lui mettant cette liste de fichiers en
paramètre.
Si j'exécute directement dans le constructeur de ma classe, ça fonctionne
bien.

Par contre, dans mon constructeur :
- J'instancie une variable global (p_files) de type HttpFileCollection, en
mettant p_Files = Files (paramètre reçu dans ma classe)
- je lance un thread (sans paramètre).
Ce thread démarre et exploite la variable globale p_files.

Voici en gros le code de mon constructeur :
public Uploading(HttpFileCollection files, ...)
{
this.p_files = files;
// Création et lancement du thread
Thread upThread = new Thread(new ThreadStart(GetData));
upThread.Start();
}

Le code précédent se trouve dans GetData.

Dans mon cas, c'est bel et bien la variable p_files qui poserait pb car le
f_files[0].InputStream ne peut pas être lu.
Est-ce que je m'y prend mal pour créer mon thread et dans la gestion des
variables ?

Merci...
--
David

"David" a écrit :

Pour info, je suis seul à utiliser le site (en dev actuellement) et je suis
donc en local également.



"Gilles TOURREAU" a écrit :

> Le Fri, 22 Jun 2007 20:00:41 +0200, Gilles TOURREAU
> >
> > Le Fri, 22 Jun 2007 18:23:05 +0200, David
> > > >
> >> En fait, je boucle sur plusieurs fichiers à uploader :
> >> HttpFileCollection p_files = Request.Files;
> >> for (int i = 0; i < this.p_files.Count; i++)
> >> {
> >> HttpPostedFile file = this.p_files[i];
> >> ... Le code vu plus bas ...
> >> }
> >>
> >> --
> >> David
> >>
> >> "Gilles TOURREAU" a écrit :
> >>
> >>> Le Fri, 22 Jun 2007 17:39:03 +0200, David
> >>> > >>>
> >>> > Bonjour,
> >>> >
> >>> > J'ai un bout de code qui me permet de faire de l'upload avec un
> >>> composant
> >>> > upload ASP.Net.
> >>> > Le code fonctionne très bien avec le serveur interne de VS.Net 2005,
> >>> par
> >>> > contre avec IIS 5 il me génère un IODisposedObject lorsque j'essaye
> >>> de
> >>> > lire
> >>> > le fichier source.
> >>> >
> >>> > Voici le code :
> >>> > // Flux d'écriture du fichier sur le serveur
> >>> > FileStream fs = new FileStream(this.p_filesNames[i],
> >>> > FileMode.OpenOrCreate);
> >>> >
> >>> > // Flux de lecture du fichier
> >>> > BinaryReader br = new BinaryReader(file.InputStream);
> >>> > try
> >>> > {
> >>> > // Tant qu'on a pas tout lu et qu'on ne doit pas stopper
> >>> > while (br.BaseStream.Length - br.BaseStream.Position > 0
> >>> &&
> >>> > !this.p_stopUpload)
> >>> > {
> >>> >
> >>> > // S'il y a moins d'octet a récupérér que la taille du
> >>> > tampon
> >>> > if (br.BaseStream.Length - br.BaseStream.Position <
> >>> > bufferSize)
> >>> > {
> >>> > bufferSize = (int)(br.BaseStream.Length -
> >>> > br.BaseStream.Position);
> >>> > }
> >>> >
> >>> > br.Read(buffer, 0, bufferSize); // lecture => il
> >>> plante ici
> >>> > !!!!!
> >>> > fs.Write(buffer, 0, bufferSize); // écriture
> >>> > this.p_totalUploaded += bufferSize;
> >>> > this.p_partialUploaded = br.BaseStream.Position;
> >>> > }
> >>> > }
> >>> > finally
> >>> > {
> >>> > // Fermeture des flux
> >>> > br.Close();
> >>> > fs.Close();
> >>> > }
> >>> >
> >>> > Et je peux vous assurer que le fichier que je veux uploader n'est pas
> >>> > ouvert
> >>> > ou utilisé par quelque chose.
> >>> > Par contre, j'ai remarqué que ça fonctionne pour des fichier < 64 Ko
> >>> !!
> >>> > Encore une fois, pour des gros fichiers, ça fonctionne avec le petit
> >>> > serveur
> >>> > interne.
> >>> > Quelle est dans IIS l'option qui déconne ?
> >>> >
> >>> > Merci pour votre aide.
> >>>
> >>> Peux-tu poster le code concernant l'utilisation de la variable : file
> >>>
> >>> Cordialement
> >>>
> >>> --
> >>> Gilles TOURREAU
> >>>
> >>>
> >>> S.A.R.L. P.O.S
> >>> Le spécialiste en motoculture depuis + de 30 ans !
> >>> http://www.pos.fr
> >>>
> >
> > Je vois pas où il y aurait un problème...
> > Cette exception est déclenché uniquement dans le cas ou vous appelez la
> > méthode Close() ou Dispose() du BinaryReader et après un Read().
> >
> > Essayez cependant cette solution qui est bien meilleur que le
> > try/finally :
> >
> > using (FileStream fs = new FileStream(this.p_filesNames[i],
> > FileMode.OpenOrCreate))
> > {
> > using (BinaryReader br = new BinaryReader(file.InputStream))
> > {
> > //... Le code
> >
> > //Inutile de faire un close à la fin des using, car la méthode
> > Dispose est automatiquement libéré...
> > }
> > }
> >
> > Cordialement
> >
> >
>
> Je viens de remarquer un truc interessant sur un de mes sites ASP...
> Quand le site "plante" (evenement Application_Error déclenché dans
> Global.asax), .NET libère toutes les ressources de toutes les demandes en
> cours en appellant la méthode Dispose() de tous les objets...
>
> Peut-être un début de piste pour toi :
> - Est-ce que ton site internet sur le IIS est utilisé par plusieurs
> utilisateurs en même temps ?
> - Si c'est le cas, cela veut dire qu'au moment du plantage, .NET appelle
> la méthode Dispose() de ton file.InputStream....
>
> Cordialement
>
> --
> Gilles TOURREAU
>
>
> S.A.R.L. P.O.S
> Le spécialiste en motoculture depuis + de 30 ans !
> http://www.pos.fr
>


Gilles TOURREAU
Le #12182391
Le Sat, 23 Jun 2007 00:31:01 +0200, David

En fait, je viens de faire des tests :
Si j'exécute le code directement sur le OnClick d'un bouton, ça
fonctionne
nickel même avec IIS !
Par contre, dans mon cas, je lance le traitement dans un thread.
Et apparemment, c'est de là que vient le pb.

En fait, je récupère la liste des fichiers dans un HttpFileCollection.
J'instancie une classe (Uploading) en lui mettant cette liste de
fichiers en
paramètre.
Si j'exécute directement dans le constructeur de ma classe, ça fonctionne
bien.

Par contre, dans mon constructeur :
- J'instancie une variable global (p_files) de type HttpFileCollection,
en
mettant p_Files = Files (paramètre reçu dans ma classe)
- je lance un thread (sans paramètre).
Ce thread démarre et exploite la variable globale p_files.

Voici en gros le code de mon constructeur :
public Uploading(HttpFileCollection files, ...)
{
this.p_files = files;
// Création et lancement du thread
Thread upThread = new Thread(new ThreadStart(GetData));
upThread.Start();
}

Le code précédent se trouve dans GetData.

Dans mon cas, c'est bel et bien la variable p_files qui poserait pb car
le
f_files[0].InputStream ne peut pas être lu.
Est-ce que je m'y prend mal pour créer mon thread et dans la gestion des
variables ?

Merci...
--
David



Non...

Je viens de faire un test qui ressemble à ce que tu souhaites (avec un
Thread) et cela fonctionne nickel...
Ce qui me chiffonne, c'est que ton erreur vient uniquement du fait que la
méthode Dispose() (ou Close()) de ton BinaryReader est appelé par
quelqu'un...

Ce que tu peux faire :

- Créer une classe MonBR qui hérite de BinaryReader
- Met le constructeur :

public MonBR(Stream s) : base(s)
{

}

- Tu "override" la méthode "protected Dispose()" :

protected override Dispose(boolean disposing)
{
//Ici on créer une fichier log qui enregistre la pile d'appel
using (StreamWriter w = new StreamWriter("C:\MonLog.txt"))
//ATTENTION au droit !!!
{
w.WriteLine(Environment.StackTrace);
}

base.Dispose(disposing);
}

Utilise maintenant cette nouvelle classe pour lire ton fichier...
Executes ton site Web sur IIS avec les fichiers .PDB cela te permettra
d'obtenir les n° de ligne au niveau de pile.

Et tu nous fais un zoli copier/coller du contenu de ce fichier quand ca
plante !

Cordialement

--
Gilles TOURREAU


S.A.R.L. P.O.S
Le spécialiste en motoculture depuis + de 30 ans !
http://www.pos.fr
David
Le #12182381
Bonjour,

Alors voici les résultats :
Si je laisse le using(MyBR br = new MyBR(p_files[0].InputStream))
Il ne va jamais dans le Dispose de mon BR car il génère une exception dans
le read.
Par contre, il y va dés que je ferme à la sauvage (Shift + F5), il me génère
un log :
à System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)
à System.Environment.get_StackTrace()
à MyBR.Dispose(Boolean disposing) dans c:.......Uploading.cs:ligne 26
(j'ai modifié le chemin)
à System.IO.BinaryReader.Close()
à Uploading.GetData() dans c:.....Uploading.cs:ligne 242 (j'ai modifié
le chemin)
à System.Threading.ThreadHelper.ThreadStart_Context(Object state)
à System.Threading.ExecutionContext.runTryCode(Object userData)
à
System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
à System.Threading.ExecutionContext.RunInternal(ExecutionContext
executionContext, ContextCallback callback, Object state)
à System.Threading.ExecutionContext.Run(ExecutionContext
executionContext, ContextCallback callback, Object state)
à System.Threading.ThreadHelper.ThreadStart()

J'ai également placé un bout de code qui me génère un log dans le
constructeur :
à System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)
à System.Environment.get_StackTrace()
à MyBR..ctor(Stream s) dans c:.....Uploading.cs:ligne 17 (j'ai modifié
le chemin)
à Uploading.GetData() dans c:.....Uploading.cs:ligne 215 (j'ai modifié
le chemin)
à System.Threading.ThreadHelper.ThreadStart_Context(Object state)
à System.Threading.ExecutionContext.runTryCode(Object userData)
à
System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
à System.Threading.ExecutionContext.RunInternal(ExecutionContext
executionContext, ContextCallback callback, Object state)
à System.Threading.ExecutionContext.Run(ExecutionContext
executionContext, ContextCallback callback, Object state)
à System.Threading.ThreadHelper.ThreadStart()

Si j'override le read, il me log bien qu'il va dans le read, et il plante
sur la ligne :
return base.Read(buffer, index, count);
avec la même exception.

Je peux faire encore des tests ?

Merci.
--
David


"Gilles TOURREAU" a écrit :

Le Sat, 23 Jun 2007 00:31:01 +0200, David

> En fait, je viens de faire des tests :
> Si j'exécute le code directement sur le OnClick d'un bouton, ça
> fonctionne
> nickel même avec IIS !
> Par contre, dans mon cas, je lance le traitement dans un thread.
> Et apparemment, c'est de là que vient le pb.
>
> En fait, je récupère la liste des fichiers dans un HttpFileCollection.
> J'instancie une classe (Uploading) en lui mettant cette liste de
> fichiers en
> paramètre.
> Si j'exécute directement dans le constructeur de ma classe, ça fonctionne
> bien.
>
> Par contre, dans mon constructeur :
> - J'instancie une variable global (p_files) de type HttpFileCollection,
> en
> mettant p_Files = Files (paramètre reçu dans ma classe)
> - je lance un thread (sans paramètre).
> Ce thread démarre et exploite la variable globale p_files.
>
> Voici en gros le code de mon constructeur :
> public Uploading(HttpFileCollection files, ...)
> {
> this.p_files = files;
> // Création et lancement du thread
> Thread upThread = new Thread(new ThreadStart(GetData));
> upThread.Start();
> }
>
> Le code précédent se trouve dans GetData.
>
> Dans mon cas, c'est bel et bien la variable p_files qui poserait pb car
> le
> f_files[0].InputStream ne peut pas être lu.
> Est-ce que je m'y prend mal pour créer mon thread et dans la gestion des
> variables ?
>
> Merci...
> --
> David

Non...

Je viens de faire un test qui ressemble à ce que tu souhaites (avec un
Thread) et cela fonctionne nickel...
Ce qui me chiffonne, c'est que ton erreur vient uniquement du fait que la
méthode Dispose() (ou Close()) de ton BinaryReader est appelé par
quelqu'un...

Ce que tu peux faire :

- Créer une classe MonBR qui hérite de BinaryReader
- Met le constructeur :

public MonBR(Stream s) : base(s)
{

}

- Tu "override" la méthode "protected Dispose()" :

protected override Dispose(boolean disposing)
{
//Ici on créer une fichier log qui enregistre la pile d'appel
using (StreamWriter w = new StreamWriter("C:\MonLog.txt"))
//ATTENTION au droit !!!
{
w.WriteLine(Environment.StackTrace);
}

base.Dispose(disposing);
}

Utilise maintenant cette nouvelle classe pour lire ton fichier...
Executes ton site Web sur IIS avec les fichiers .PDB cela te permettra
d'obtenir les n° de ligne au niveau de pile.

Et tu nous fais un zoli copier/coller du contenu de ce fichier quand ca
plante !

Cordialement

--
Gilles TOURREAU


S.A.R.L. P.O.S
Le spécialiste en motoculture depuis + de 30 ans !
http://www.pos.fr



David
Le #12182371
Je viens de découvrir autre chose :
Lorsque j'analyse le nom du fichier représentant mon stream, (dans
Basestream), il est censé se trouver dans :
"C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET
Files\AppName\7f6dd88d\8cb3e2bc\uploads\_dt8z4nw.post"
Hors, il ne s'y trouve pas !
Il n'y a pas de fichier !!!
Du coup, c'est peut-être ça le pb, il devrait me le créer, mais il n'y a
rien...
Par contre, je ne vois pas le lien entre l'absence de ce fichier et la
création d'un thread.
Je rappel que si j'exécute mon code ailleurs que dans un thread ça
fonctionne bien.
D'ailleurs, j'ai vérifié, le fichier .post temporaire existe bien...

--
David


"Gilles TOURREAU" a écrit :

Le Sat, 23 Jun 2007 00:31:01 +0200, David

> En fait, je viens de faire des tests :
> Si j'exécute le code directement sur le OnClick d'un bouton, ça
> fonctionne
> nickel même avec IIS !
> Par contre, dans mon cas, je lance le traitement dans un thread.
> Et apparemment, c'est de là que vient le pb.
>
> En fait, je récupère la liste des fichiers dans un HttpFileCollection.
> J'instancie une classe (Uploading) en lui mettant cette liste de
> fichiers en
> paramètre.
> Si j'exécute directement dans le constructeur de ma classe, ça fonctionne
> bien.
>
> Par contre, dans mon constructeur :
> - J'instancie une variable global (p_files) de type HttpFileCollection,
> en
> mettant p_Files = Files (paramètre reçu dans ma classe)
> - je lance un thread (sans paramètre).
> Ce thread démarre et exploite la variable globale p_files.
>
> Voici en gros le code de mon constructeur :
> public Uploading(HttpFileCollection files, ...)
> {
> this.p_files = files;
> // Création et lancement du thread
> Thread upThread = new Thread(new ThreadStart(GetData));
> upThread.Start();
> }
>
> Le code précédent se trouve dans GetData.
>
> Dans mon cas, c'est bel et bien la variable p_files qui poserait pb car
> le
> f_files[0].InputStream ne peut pas être lu.
> Est-ce que je m'y prend mal pour créer mon thread et dans la gestion des
> variables ?
>
> Merci...
> --
> David

Non...

Je viens de faire un test qui ressemble à ce que tu souhaites (avec un
Thread) et cela fonctionne nickel...
Ce qui me chiffonne, c'est que ton erreur vient uniquement du fait que la
méthode Dispose() (ou Close()) de ton BinaryReader est appelé par
quelqu'un...

Ce que tu peux faire :

- Créer une classe MonBR qui hérite de BinaryReader
- Met le constructeur :

public MonBR(Stream s) : base(s)
{

}

- Tu "override" la méthode "protected Dispose()" :

protected override Dispose(boolean disposing)
{
//Ici on créer une fichier log qui enregistre la pile d'appel
using (StreamWriter w = new StreamWriter("C:\MonLog.txt"))
//ATTENTION au droit !!!
{
w.WriteLine(Environment.StackTrace);
}

base.Dispose(disposing);
}

Utilise maintenant cette nouvelle classe pour lire ton fichier...
Executes ton site Web sur IIS avec les fichiers .PDB cela te permettra
d'obtenir les n° de ligne au niveau de pile.

Et tu nous fais un zoli copier/coller du contenu de ce fichier quand ca
plante !

Cordialement

--
Gilles TOURREAU


S.A.R.L. P.O.S
Le spécialiste en motoculture depuis + de 30 ans !
http://www.pos.fr



Publicité
Poster une réponse
Anonyme