问题
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?
回答1:
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
}
}
来源:https://stackoverflow.com/questions/19563753/windows-phone-isolatedstorage