【问题标题】:Windows Phone IsolatedStorageWindows Phone 隔离存储
【发布时间】:2013-10-24 10:45:29
【问题描述】:

我有一个应用程序需要在设备上下载和保存文件 - 视频。

视频很短,大约 10 分钟,质量很差,这意味着它们的尺寸很小。

所以,问题是当我下载一些文件时 - 一切顺利,但有些文件失败并出现错误: 内存不足异常。从逻辑上讲,我认为小于某个大小(例如 50MB)的文件可以很好地下载,但更高 - 例外。

这是我的代码:

private void btnDownload2_Click(object sender, RoutedEventArgs e)
    {
        WebClient webClient = new WebClient();
        webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(webClient_DownloadProgressChanged);
        webClient.OpenReadCompleted += new OpenReadCompletedEventHandler(webClient_OpenReadCompleted);
        webClient.OpenReadAsync(new Uri("http://somelink/video/nameOfFile.mp4"));
    }

void webClient_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
    {
        try
        {
            if (progressMedia.Value <= progressMedia.Maximum)
            {
                progressMedia.Value = (double)e.ProgressPercentage;
            }

        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

    protected bool IncreaseIsolatedStorageSpace(long quotaSizeDemand)
    {
        bool CanSizeIncrease = false;
        IsolatedStorageFile isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication();
        //Get the Available space
        long maxAvailableSpace = isolatedStorageFile.AvailableFreeSpace;
        if (quotaSizeDemand > maxAvailableSpace)
        {
            if (!isolatedStorageFile.IncreaseQuotaTo(isolatedStorageFile.Quota + quotaSizeDemand))
            {
                CanSizeIncrease = false;
                return CanSizeIncrease;
            }
            CanSizeIncrease = true;
            return CanSizeIncrease;
        }
        return CanSizeIncrease;
    }

    void webClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
    {
        try
        {
            if (e.Result != null)
            {

                #region Isolated Storage Copy Code
                isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication();

                bool checkQuotaIncrease = IncreaseIsolatedStorageSpace(e.Result.Length);

                string VideoFile = "PlayFile.wmv";
                isolatedStorageFileStream = new IsolatedStorageFileStream(VideoFile, FileMode.Create, isolatedStorageFile);
                long VideoFileLength = (long)e.Result.Length;
                byte[] byteImage = new byte[VideoFileLength];
                e.Result.Read(byteImage, 0, byteImage.Length);
                isolatedStorageFileStream.Write(byteImage, 0, byteImage.Length);

                #endregion

                mediaFile.SetSource(isolatedStorageFileStream);
                mediaFile.Play();
                progressMedia.Visibility = Visibility.Collapsed;


            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

    private void mediaFile_MediaEnded(object sender, RoutedEventArgs e)
    {
        MessageBoxResult res = MessageBox.Show("Do you want to Replay the file", "Decide", MessageBoxButton.OKCancel);

        if (res == MessageBoxResult.OK)
        {
            mediaFile.Play();
        }
        else
        {
            isolatedStorageFileStream.Close();
            isolatedStorageFile.Dispose();
            mediaFile.ClearValue(MediaElement.SourceProperty);
        }
    }

异常详情:

System.OutOfMemoryException 未处理 消息:未处理 'System.OutOfMemoryException' 类型的异常发生在 System.Windows.ni.dll

异常图片:

有解决办法吗?

【问题讨论】:

    标签: c# windows-phone-7 windows-phone-8 windows-phone isolatedstorage


    【解决方案1】:

    在完全加载响应时,它完全驻留在内存中。这会导致您的 OutOfMemoryException。解决方案是将响应直接“流式传输”到隔离存储中。

    请注意,以下解决方案目前的缺点是您会丢失下载进度信息。

    public async void btnDownload2_Click()
    {
      try
      {
        var httpClient = new HttpClient();
        var response = await httpClient.GetAsync(new Uri("http://somelink/video/nameOfFile.mp4"), HttpCompletionOption.ResponseHeadersRead);
    
        response.EnsureSuccessStatusCode();
    
        using(var isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication())
        {
          bool checkQuotaIncrease = IncreaseIsolatedStorageSpace(e.Result.Length);
    
          string VideoFile = "PlayFile.wmv";
          using(var isolatedStorageFileStream = new IsolatedStorageFileStream(VideoFile, FileMode.Create, isolatedStorageFile))
          {
            using(var stm = await response.Content.ReadAsStreamAsync())
            {
              stm.CopyTo(isolatedStorageFileStream);
            }
          }
        }
      }
      catch(Exception)
      {
        // TODO: add error handling
      }
    }
    

    【讨论】:

    • 但是HTTP客户端只能在4.5+框架和windows phone 8上使用。但是我的应用需要移植到WP7+上
    • 所以正确的问题是,如何实现从 WebClient 或 HTTP 客户端直接保存到隔离存储
    • WP7.5 支持 HttpClient。甚至包括异步/等待支持。看到这个页面:blogs.msdn.com/b/bclteam/archive/2013/02/18/…
    • 或者您可以将我的示例移植到 HttpWebRequest -> msdn.microsoft.com/en-us/library/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多