2010-01-21 6 views
0

Utilisation de Silverlight 3 pour créer une application de téléchargement de fichiers. Il peut télécharger des fichiers de n'importe quelle taille - cela fonctionne (selon les circonstances) avec des fichiers de 4 Go. Il télécharge des morceaux de fichiers, de sorte que si quelque chose se produit, le téléchargement peut être repris à partir du bloc le plus récent.Problème de mémoire de téléchargement de fichier Silverlight

La circonstance où le téléchargement ne fonctionne pas est dans IE et Chrome lors du téléchargement de fichiers volumineux. Ils semblent avoir des problèmes de mémoire. Dans Firefox, l'utilisation de la mémoire est une ligne irrégulière - comme on pouvait s'y attendre si elle lisait une partie du fichier, la téléchargeait, la rejetait, puis recommençait sur le morceau suivant. IE et Chrome semblent s'accrocher aux morceaux. Finalement, une exception OutOfMemoryException est levée une fois que la RAM disponible est épuisée. Jusqu'ici, j'ai essayé de changer le flux de fichier et les tailles de flux, les buffers, etc. J'ai essayé de générer des octets plutôt que de lire le flux de fichiers - mêmes problèmes. J'ai essayé d'écrire tout un morceau à la fois plutôt que le tampon 4kb que nous utilisons maintenant - mêmes problèmes.

Des idées sur ce qui pourrait se passer? IE et Chrome ne sont-ils pas en train de collecter des ordures pour se débarrasser des morceaux inutiles? Ou y a-t-il un en-tête de requête http que je devrais utiliser? Quelques idées sur la façon de localiser où la mémoire est utilisée - dans IE lui-même, ou le plugin Silverlight?

+0

@ndim merci pour avoir corrigé les fautes de frappe – cofiem

+1

Pouvez-vous essayer de simuler le téléchargement, sans envoyer de données, mais simplement lire le fichier en morceaux, convertir en octets, et continuer? –

+0

Bonne idée ... J'y reviendrai quand je le pourrai, et j'essaierai ça. – cofiem

Répondre

0

Je ne pouvais pas déterminer ce qui se passait ici, même après mise à niveau vers Silverlight 4. Désolé, je ne peux pas être plus utile.

1

J'ai rencontré à peu plus le même scénario quand je voulais exporter des données de mon application silverlight dans un fichier .csv. Dans Internet Explorer, je n'ai pas pu enregistrer le fichier car la requête n'a pas été envoyée au gestionnaire http que j'utilisais pour récupérer des données.

Le code initial était comme ça:

 HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(new Uri(url, UriKind.Absolute)); 
      request.BeginGetResponse(new AsyncCallback(ReadExportHandlerCallback), request); 

mais il ne fonctionne pas dans IE. Fiddler m'a montré que les demandes ne sont pas envoyées au gestionnaire http et je ne savais pas pourquoi cela arrivait.

Je suis venu avec la solution suivante: utilisez un flux (mémoire, fichier) pour envoyer la requête au gestionnaire et les méthodes asynchrones BeginRequestStream() et EndGetRequestStream().

// other code. 
    { 
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri(url, UriKind.Absolute)); 

      MemoryStream mStream = new MemoryStream(); 
      var uploadRequest = new UploadRequest 
        { 
         MemoryStream = mStream, 
         Request = request 
        }; 

      request.Method = "POST"; 
      request.BeginGetRequestStream(OnGetRequestStream, uploadRequest);     
    } 


    public void OnGetRequestStream(IAsyncResult result) 
    { 
     var uploadRequest = (UploadRequest)result.AsyncState;    
     uploadRequest.MemoryStream.Seek(0, SeekOrigin.Begin); 
     try 
     { 
      // upload bytes to the server 
      using (var stream = uploadRequest.Request.EndGetRequestStream(result)) 
      { 
       var buffer = new byte[uploadRequest.MemoryStream.Length]; 
       int bytesRead; 

       while ((bytesRead = uploadRequest.MemoryStream.Read(buffer, 0,     buffer.Length)) != 0) 
       { 
        stream.Write(buffer, 0, bytesRead); 
       } 
      } 

      // async get response     
      uploadRequest.Request.BeginGetResponse(new AsyncCallback(ReadExportHandlerCallback), uploadRequest); 
     } 
     catch (Exception) 
     { 

     } 
     finally 
     { 
      // ensure file is properly closed after sending either succeeded or failed 
      uploadRequest.MemoryStream.Close(); 
     } 
    }  

    private void ReadExportHandlerCallback(IAsyncResult asynchronousResult) 
    {    
     var uploadRequest = (UploadRequest)asynchronousResult.AsyncState; 
     var response = (HttpWebResponse)uploadRequest.Request.EndGetResponse(asynchronousResult); 

     using (StreamReader streamReader = new StreamReader(response.GetResponseStream())) 
     { 
      _data = streamReader.ReadToEnd(); 
      _dataReceived = true; 
     }    
    } 

La classe UploadRequest est une classe personnalisée qui contient 2 propriétés: un MemoryStream et un HttpWebRequest.

public class UploadRequest 
{ 
    #region Fields 

    private MemoryStream _memoryStream; 
    private HttpWebRequest _httpWebRequest; 

    #endregion 

    #region Properties 

    /// <summary> 
    /// The stream that will be sent to the handler. 
    /// </summary> 
    public MemoryStream MemoryStream 
    { 
     get 
     { 
      return _memoryStream; 
     } 
     set 
     { 
      _memoryStream = value; 
     } 
    } 

    /// <summary> 
    /// The request that contains the stream. 
    /// </summary> 
    public HttpWebRequest Request 
    { 
     get 
     { 
      return _httpWebRequest; 
     } 
     set 
     { 
      _httpWebRequest = value; 
     } 
    } 

Hope that helps!

Questions connexes