简体   繁体   中英

Windows Phone IsolatedStorage

I have a application that needs to download and save files on a device - videos.

Videos are short ~ 10min and in poor quality, which means that their size is minimal.

So, the problem is that when i download some files - all goes nice, but some files fail with error: Out of memory exception. Logically i think that files less than some size ( for example 50MB ) download nicely, but higher - exception.

Here is my code:

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);
        }
    }

Exception details:

System.OutOfMemoryException was unhandled Message: An unhandled exception of type 'System.OutOfMemoryException' occurred in System.Windows.ni.dll

Exception image:

在此处输入图片说明

Is there a workaround for this?

At the time the response is completely loaded, it resides entirely in memory. This is causing your OutOfMemoryException. The solution is to "stream" the response directly into isolated storage.

Please note that the solution below currently has the drawback that you are losing download progress information.

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
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM