Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Upload avec IIS : Fichier fermé

23 réponses
Avatar
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.

10 réponses

1 2 3
Avatar
Gilles TOURREAU
Le Sat, 23 Jun 2007 15:25:01 +0200, David
a écrit:

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



Je viens de penser à un truc...
Peux-tu refaire le test en mettant append = true au niveau du constructeur
du StreamWriter du log :

using (StreamReader r = new StreamReader("C:...", true))
{
r.WriteLine();
r.WriteLine();
r.WriteLine("********************");

//Les lignes au dessus permettent de bien séparer les différents appel
à Dispose().

r.WriteLine(Environnement.StackTrace);
}

Car sinon, cela recréer le fichier de log... Et on ne peux pas voir si la
méthode Dispose() est appelé plus d'une fois !

Cordialement

--
Gilles TOURREAU


S.A.R.L. P.O.S
Le spécialiste en motoculture depuis + de 30 ans !
http://www.pos.fr
Avatar
Voici le résultat :
à System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)
à System.Environment.get_StackTrace()
à MyBR.Dispose(Boolean disposing) dans c:......Uploading.cs:ligne 26
à System.IO.BinaryReader.System.IDisposable.Dispose()
à Uploading.GetData() dans c:......Uploading.cs:ligne 241
à 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()
à System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)
à System.Environment.get_StackTrace()
à MyBR..ctor(Stream s) dans c:......Uploading.cs:ligne 17
à Uploading.GetData() dans c:......Uploading.cs:ligne 281
à 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()
à System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)
à System.Environment.get_StackTrace()
à MyBR.Read(Byte[] buffer, Int32 index, Int32 count) dans
c:......Uploading.cs:ligne 35
à Uploading.GetData() dans c:......Uploading.cs:ligne 294
à 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()

Mais encore une fois je pense que ça vient du fichier .post dans le
répertoire upload des asp.net temporary files qui disparait dés lors que le
thread démarre.
Ce fichier .post correspond exactement au fichier de mon inpustream
(p_files[0])
Comme il disparait, il essaye de lire un fichier qui n'existe pas et alors
il génère l'exception (ce que je comprends).
Par contre, pourquoi ce fichier disparait ?
Qui le fait disparaitre ?

--
David

"Gilles TOURREAU" a écrit dans le message de news:

Le Sat, 23 Jun 2007 15:25:01 +0200, David
a écrit:

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



Je viens de penser à un truc...
Peux-tu refaire le test en mettant append = true au niveau du constructeur
du StreamWriter du log :

using (StreamReader r = new StreamReader("C:...", true))
{
r.WriteLine();
r.WriteLine();
r.WriteLine("********************");

//Les lignes au dessus permettent de bien séparer les différents appel
à Dispose().

r.WriteLine(Environnement.StackTrace);
}

Car sinon, cela recréer le fichier de log... Et on ne peux pas voir si la
méthode Dispose() est appelé plus d'une fois !

Cordialement

--
Gilles TOURREAU


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


Avatar
Gilles TOURREAU
Le Sun, 24 Jun 2007 01:34:19 +0200, <d> a écrit:

Voici le résultat :
à System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)
à System.Environment.get_StackTrace()
à MyBR.Dispose(Boolean disposing) dans c:......Uploading.cs:ligne 26
à System.IO.BinaryReader.System.IDisposable.Dispose()
à Uploading.GetData() dans c:.....Uploading.cs:ligne 241
à 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()
à System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)
à System.Environment.get_StackTrace()
à MyBR..ctor(Stream s) dans c:......Uploading.cs:ligne 17
à Uploading.GetData() dans c:......Uploading.cs:ligne 281
à 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()
à System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)
à System.Environment.get_StackTrace()
à MyBR.Read(Byte[] buffer, Int32 index, Int32 count) dans
c:......Uploading.cs:ligne 35
à Uploading.GetData() dans c:......Uploading.cs:ligne 294
à 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()

Mais encore une fois je pense que ça vient du fichier .post dans le
répertoire upload des asp.net temporary files qui disparait dés lors que
le
thread démarre.
Ce fichier .post correspond exactement au fichier de mon inpustream
(p_files[0])
Comme il disparait, il essaye de lire un fichier qui n'existe pas et
alors
il génère l'exception (ce que je comprends).
Par contre, pourquoi ce fichier disparait ?
Qui le fait disparaitre ?




Windows ne peut pas supprimer/déplacer/renommer un fichier qui est ouvert
par un autre processus. C'est à dire que si tu fais :

using (BinaryReader br = new BinaryReader(Stream))
{
...
}

Quand tu es dans le using cela veut dire :
- Le fichier existe bien, sinon le constructeur aurait déclenché une
exception
- Le fichier est forcement "bloqué" et ne peut être supprimé

Le seul moyen de "débloqué" le fichier est d'appeler la méthode Dispose()
de ton Stream...

Maintenant si tu as un ObjectDisposedException cela vient tout simplement
du fais que soit la méthode Dispose() a été appelé dans le BR, soit dans
le Stream sous-adjacent avant ton Read().

Comme ton fichier disparait, je pencherai plus à l'appelle de Dispose() du
Stream sous-adjacent (car à ce moment là ASP .NET peut après le Dispose()
supprimer le fichier .post.).
En regardant le code source du Framework, le seul endroit où la libération
du fichier temporaire est réalisée c'est quand la requête (objet Request)
est libérée... Et là je ne sais pas pourquoi la requête est
automatiquement libéré sous IIS contrairement au petit serveur web de VS.
Peut être un paramètrage ?

Cependant est-ce que tu peux montrer les alentours des lignes 281, 241 et
294 de Uploading.cs ?

Cordialement

--
Gilles TOURREAU


S.A.R.L. P.O.S
Le spécialiste en motoculture depuis + de 30 ans !
http://www.pos.fr
Avatar
Je pense en effet que ce n'est pas Windows mais le Framework 2.0 qui
supprime ses fichiers temporaires.
Tu as raison, je pense que c'est du genre l'objet Request qui doit être
liberé lors du lancement du thread.
Le fichier est supprimé et il essaye de lire le .post qui n'existe plus et
génère l'exception.
Maintenant pourquoi les deux serveurs se comportent-ils différemment ?

Pour info, voici le code pour les lignes :
241 :
using (MyBR br = new MyBR(file.InputStream))
281 :
br.Read(buffer, 0, bufferSize); // lecture
294 :
} (acolade fermante du using)

En gros, c'est le code déjà posté :
using (MyBR br = new MyBR(file.InputStream))
{
br.BaseStream.Position = 0;
// 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
fs.Write(buffer, 0, bufferSize); // écriture
this.p_totalUploaded += bufferSize;
this.p_partialUploaded = br.BaseStream.Position;

}
}

--
David


"Gilles TOURREAU" a écrit dans le message de news:

Le Sun, 24 Jun 2007 01:34:19 +0200, <d> a écrit:

Voici le résultat :
à System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)
à System.Environment.get_StackTrace()
à MyBR.Dispose(Boolean disposing) dans c:......Uploading.cs:ligne 26
à System.IO.BinaryReader.System.IDisposable.Dispose()
à Uploading.GetData() dans c:.....Uploading.cs:ligne 241
à 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()
à System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)
à System.Environment.get_StackTrace()
à MyBR..ctor(Stream s) dans c:......Uploading.cs:ligne 17
à Uploading.GetData() dans c:......Uploading.cs:ligne 281
à 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()
à System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)
à System.Environment.get_StackTrace()
à MyBR.Read(Byte[] buffer, Int32 index, Int32 count) dans
c:......Uploading.cs:ligne 35
à Uploading.GetData() dans c:......Uploading.cs:ligne 294
à 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()

Mais encore une fois je pense que ça vient du fichier .post dans le
répertoire upload des asp.net temporary files qui disparait dés lors que
le
thread démarre.
Ce fichier .post correspond exactement au fichier de mon inpustream
(p_files[0])
Comme il disparait, il essaye de lire un fichier qui n'existe pas et
alors
il génère l'exception (ce que je comprends).
Par contre, pourquoi ce fichier disparait ?
Qui le fait disparaitre ?




Windows ne peut pas supprimer/déplacer/renommer un fichier qui est ouvert
par un autre processus. C'est à dire que si tu fais :

using (BinaryReader br = new BinaryReader(Stream))
{
...
}

Quand tu es dans le using cela veut dire :
- Le fichier existe bien, sinon le constructeur aurait déclenché une
exception
- Le fichier est forcement "bloqué" et ne peut être supprimé

Le seul moyen de "débloqué" le fichier est d'appeler la méthode Dispose()
de ton Stream...

Maintenant si tu as un ObjectDisposedException cela vient tout simplement
du fais que soit la méthode Dispose() a été appelé dans le BR, soit dans
le Stream sous-adjacent avant ton Read().

Comme ton fichier disparait, je pencherai plus à l'appelle de Dispose() du
Stream sous-adjacent (car à ce moment là ASP .NET peut après le Dispose()
supprimer le fichier .post.).
En regardant le code source du Framework, le seul endroit où la libération
du fichier temporaire est réalisée c'est quand la requête (objet Request)
est libérée... Et là je ne sais pas pourquoi la requête est
automatiquement libéré sous IIS contrairement au petit serveur web de VS.
Peut être un paramètrage ?

Cependant est-ce que tu peux montrer les alentours des lignes 281, 241 et
294 de Uploading.cs ?

Cordialement

--
Gilles TOURREAU


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


Avatar
Gilles TOURREAU
Le Sun, 24 Jun 2007 22:29:40 +0200, <d> a écrit:

Je pense en effet que ce n'est pas Windows mais le Framework 2.0 qui
supprime ses fichiers temporaires.
Tu as raison, je pense que c'est du genre l'objet Request qui doit être
liberé lors du lancement du thread.
Le fichier est supprimé et il essaye de lire le .post qui n'existe plus
et
génère l'exception.
Maintenant pourquoi les deux serveurs se comportent-ils différemment ?

Pour info, voici le code pour les lignes :
241 :
using (MyBR br = new MyBR(file.InputStream))
281 :
br.Read(buffer, 0, bufferSize); // lecture
294 :
} (acolade fermante du using)

En gros, c'est le code déjà posté :
using (MyBR br = new MyBR(file.InputStream))
{
br.BaseStream.Position = 0;
// 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
fs.Write(buffer, 0, bufferSize); // écriture
this.p_totalUploaded += bufferSize;
this.p_partialUploaded = br.BaseStream.Position;

}
}

--
David



Est-tu sur de tes n° de lignes ?
Parceque selon la trace que tu m'as passé, la ligne 241 appelle
BR.Dispose(), la ligne 281 appelle le constructeur de BR et la ligne 294
la méthode Read()... As-tu des fonctions privées intermédiaire ?

Cordialement

--
Gilles TOURREAU


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

Alors j'ai refait les tests car j'ai changé mon code depuis, mais je pense
être revenu à l'origine (mise à part les numéros de lignes).
Donc, voici les résultats :
à System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)
à System.Environment.get_StackTrace()
à MyBR..ctor(Stream s) dans c:.....Uploading.cs:ligne 17
à Uploading.GetData() dans c:.....Uploading.cs:ligne 293
à 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()
à System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)
à System.Environment.get_StackTrace()
à MyBR.Read(Byte[] buffer, Int32 index, Int32 count) dans
c:.....Uploading.cs:ligne 35
à Uploading.GetData() dans c:.....Uploading.cs:ligne 304
à 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()
----> Exception à ce niveau là
----> aprsè, je fais Shift+F5 => il va disposer MyBR :
à System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)
à System.Environment.get_StackTrace()
à MyBR.Dispose(Boolean disposing) dans c:.....Uploading.cs:ligne 26
à System.IO.BinaryReader.System.IDisposable.Dispose()
à Uploading.GetData() dans c:.....Uploading.cs:ligne 311
à 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()

Ligne 17 :
w.WriteLine(Environment.StackTrace); (dans le constructeur de MyBR)
Ligne 293 :
using (MyBR br = new MyBR(file.InputStream))
Ligne 304 :
br.Read(buffer, 0, bufferSize); // lecture
Ligne 26 :
w.WriteLine(Environment.StackTrace); (du Dispose de MyBR)
Ligne 311 :
} (fermant de mon using précédent)

Pour info, j'ai fait tourné le même code avec le serveur interne et il
boucle bien sur les read()

Le pire, c'est que je n'ai pas d'idée de comment contourner mon pb.
--
David

"Gilles TOURREAU" a écrit :

Le Sun, 24 Jun 2007 22:29:40 +0200, <d> a écrit:

> Je pense en effet que ce n'est pas Windows mais le Framework 2.0 qui
> supprime ses fichiers temporaires.
> Tu as raison, je pense que c'est du genre l'objet Request qui doit être
> liberé lors du lancement du thread.
> Le fichier est supprimé et il essaye de lire le .post qui n'existe plus
> et
> génère l'exception.
> Maintenant pourquoi les deux serveurs se comportent-ils différemment ?
>
> Pour info, voici le code pour les lignes :
> 241 :
> using (MyBR br = new MyBR(file.InputStream))
> 281 :
> br.Read(buffer, 0, bufferSize); // lecture
> 294 :
> } (acolade fermante du using)
>
> En gros, c'est le code déjà posté :
> using (MyBR br = new MyBR(file.InputStream))
> {
> br.BaseStream.Position = 0;
> // 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
> fs.Write(buffer, 0, bufferSize); // écriture
> this.p_totalUploaded += bufferSize;
> this.p_partialUploaded = br.BaseStream.Position;
>
> }
> }
>
> --
> David

Est-tu sur de tes n° de lignes ?
Parceque selon la trace que tu m'as passé, la ligne 241 appelle
BR.Dispose(), la ligne 281 appelle le constructeur de BR et la ligne 294
la méthode Read()... As-tu des fonctions privées intermédiaire ?

Cordialement

--
Gilles TOURREAU


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



Avatar
Gilles TOURREAU
Le Mon, 25 Jun 2007 14:42:02 +0200, David
a écrit:

Là je ne vois pas du tout où est ton problème...

As-tu essayé la méthode HttpPostedFile.SaveAs() ?

Cordialement

--
Gilles TOURREAU


S.A.R.L. P.O.S
Le spécialiste en motoculture depuis + de 30 ans !
http://www.pos.fr
Avatar
Patrice
Objectif de l'utilisation d'un thread ? A mon avis, le thread continue à
s'exécuter alors que la requête HTTP est déjà finie (bloques tu la requête
en attente de la fin de ce thread ?) donc les données téléchargées (les
fichiers) deviennent indisponibles pendant l'exécution de ce thread.

--
Patrice

"David" a écrit dans le message de news:

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
> a écrit:
>
> > Le Fri, 22 Jun 2007 18:23:05 +0200, David
> > a écrit:
> >
> >> 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
> >>> a écrit:
> >>>
> >>> > 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
>




Avatar
David
En fait, même avec le SaveAs ça fait la même erreur.

J'ai eu confirmation par d'autres personnes que si mon fichier disparait,
c'est normal.
En gros, voici le déroulement :
- je suis dans ma WebForm, je valide mon formulaire et dans le code .cs,
j'appelle le constructeur d'une classe Uploading en lui passant en paramètre
Request.Files
- J'arrive dans le constructeur (tout va bien, je récupère mon
HttpFileCollection)
- Je lance un thread qui fait le traitement sur mes fichiers (il utilise une
variable provée à ma classe pour récupérer les fichiers)
- A ce moment, le serveur quitte le code de ma webform appelante

Ce qu'on me dit :
L'objet Request est alors disposé et les fichiers avec !!!
Du coup, je me retrouve dans mon thread sans fichier...

On m'a conseillé de faire un clone de mon HttpFileCollection juste avant
d'appeler mon thread.
Je suis Ok, mais comment ????
As-tu une idée ?
Merci.

--
David

"Gilles TOURREAU" a écrit :

Le Mon, 25 Jun 2007 14:42:02 +0200, David
a écrit:

Là je ne vois pas du tout où est ton problème...

As-tu essayé la méthode HttpPostedFile.SaveAs() ?

Cordialement

--
Gilles TOURREAU


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



Avatar
Gilles TOURREAU
Le Mon, 25 Jun 2007 19:03:02 +0200, David
a écrit:

En fait, même avec le SaveAs ça fait la même erreur.

J'ai eu confirmation par d'autres personnes que si mon fichier disparait,
c'est normal.
En gros, voici le déroulement :
- je suis dans ma WebForm, je valide mon formulaire et dans le code .cs,
j'appelle le constructeur d'une classe Uploading en lui passant en
paramètre
Request.Files
- J'arrive dans le constructeur (tout va bien, je récupère mon
HttpFileCollection)
- Je lance un thread qui fait le traitement sur mes fichiers (il utilise
une
variable provée à ma classe pour récupérer les fichiers)
- A ce moment, le serveur quitte le code de ma webform appelante

Ce qu'on me dit :
L'objet Request est alors disposé et les fichiers avec !!!
Du coup, je me retrouve dans mon thread sans fichier...

On m'a conseillé de faire un clone de mon HttpFileCollection juste avant
d'appeler mon thread.
Je suis Ok, mais comment ????
As-tu une idée ?
Merci.

--
David

"Gilles TOURREAU" a écrit :

Le Mon, 25 Jun 2007 14:42:02 +0200, David
a écrit:

Là je ne vois pas du tout où est ton problème...

As-tu essayé la méthode HttpPostedFile.SaveAs() ?

Cordialement

--
Gilles TOURREAU


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






Malheureusement, tu ne peux pas cloner les HttpPostedFile, ni la
collection...

Au fait, quelle version d'IIS utilises-tu ?

--
Gilles TOURREAU


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