Проблема с загрузкой файлов Silverlight - PullRequest
0 голосов
/ 21 января 2010

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

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

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

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

Ответы [ 2 ]

1 голос
/ 13 октября 2011

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

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

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

но это не сработало в IE. Fiddler показал мне, что запросы не отправляются обработчику 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 свойства: поток памяти и 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;
        }
    }

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

0 голосов
/ 07 сентября 2010

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

...