2010-01-21 3 views
0

Использование Silverlight 3 для создания приложения для загрузки файлов. Он может загружать файлы практически любого размера - он работает (в зависимости от обстоятельств) с файлами размером 4 ГБ. Он загружает фрагменты файлов, так что, если что-то случится, загрузка может быть возобновлена ​​с самого последнего фрагмента.Проблема с загрузкой файла Silverlight

Сведения о том, что загрузка не работает, в IE и Chrome при загрузке больших файлов. У них, похоже, проблемы с памятью. В Firefox использование памяти - это зубчатая линия - как и ожидалось, если бы она читала кусок файла, загружала его, отбрасывая, а затем снова начинала на следующем фрагменте. IE и Chrome, похоже, держатся за куски. В конечном итоге исключение OutOfMemoryException выбрасывается, когда израсходовано доступное ОЗУ.

До сих пор я пытался изменить потоки файлов и потоки веб-запросов, буферы и т. Д. Я пытался просто генерировать байты, а не читать из потока файлов - те же проблемы. Я попробовал просто написать целый кусок одновременно, а не 4kb-буфер, который мы используем сейчас - те же проблемы.

Любые идеи о том, что может произойти? Могут ли IE и Chrome просто не собирать мусор, чтобы избавиться от кусков, которые не нужны? Или есть какой-то заголовок http-запроса, который я должен использовать? Некоторые идеи о том, как определить, где используется память - в самом IE или в плагине Silverlight?

+0

@ndim спасибо за исправление опечаток – cofiem

+1

Можете ли вы попробовать имитировать загрузку без фактической отправки каких-либо данных, а просто просто прочитать файл в кусках, преобразовать в байты и продолжить? –

+0

Хорошая идея ... Я вернусь к этому, когда смогу, и попробую это. – cofiem

ответ

0

Я не мог определить, что здесь происходит, даже после перехода на Silverlight 4. Извините, я не могу быть более полезным.

1

Я встретил почти такой же сценарий, когда мне захотелось экспортировать данные из моего приложения silverlight в CSV-файл. В Internet Explorer я не смог сохранить файл, потому что запрос не был отправлен обработчику http, который я использовал для извлечения данных.

Исходный код был таким:

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

, но он не работает в IE. Скрипач показал мне, что запросы не отправляются обработчику http, и я не знал, почему это происходит.

Я пришел к следующему решению: используйте поток (память, файл), чтобы отправить запрос обработчику и асинхронным методам BeginRequestStream() и 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; 
     }    
    } 

Класс UploadRequest является пользовательский класс, который содержит 2 свойства: MemoryStream и 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; 
     } 
    } 

Надеюсь, что это поможет!

Смежные вопросы