1

デバイスにファイルをダウンロードして保存する必要があるアプリケーションがあります-ビデオ。

動画は 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.Windows.ni.dll で 'System.OutOfMemoryException' 型の未処理の例外が発生しました

例外画像:

ここに画像の説明を入力

これに対する回避策はありますか?

4

1 に答える 1

0

応答が完全に読み込まれると、応答は完全にメモリ内に存在します。これが 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
  }
}
于 2013-10-24T11:00:59.230 に答える