I am using Lumia 640 for development.
I got an memory out of exception in windows phone 8.1 Silver Light Application.
I have tried to dispose stream, remove bitmap from memory but still facing this issues.
When collecting More than 5 Images using CameraCaptureTask it will throws "memory out of exception".
I am posing My Demo Code Here.
private void Button_Click(object sender, RoutedEventArgs e)
{
CameraCaptureTask cameraCaptureTask = new CameraCaptureTask();
cameraCaptureTask.Show();
cameraCaptureTask.Completed += new EventHandler<PhotoResult>(this.CameraCaptureTaskCompleted);
}
private async void CameraCaptureTaskCompleted(object sender, PhotoResult e)
{
if (e.TaskResult == TaskResult.OK)
{
Debug.WriteLine("[ApplicationCurrentMemoryUsage](MB) : \n" + (DeviceStatus.ApplicationCurrentMemoryUsage / 1024 / 1024));
Image attachedImage = new Image();
Stream fileStream = e.ChosenPhoto;
string strFolderName = "Capture";
IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication();
var fileName = Guid.NewGuid() + ".JPG";
if (!isf.DirectoryExists(strFolderName))
{
isf.CreateDirectory(strFolderName);
}
if (isf.FileExists(strFolderName + "\\" + fileName))
{
isf.DeleteFile(strFolderName + "\\" + fileName);
}
IsolatedStorageFileStream isfs = isf.CreateFile(strFolderName + "\\" + fileName);
int bytesRead = 0;
var bufferSize = Convert.ToInt32(fileStream.Length);
var fileBytes = new byte[fileStream.Length];
while ((bytesRead = await fileStream.ReadAsync(fileBytes, 0, bufferSize)) > 0)
{
isfs.Write(fileBytes, 0, bytesRead);
}
BitmapImage bitImage = new BitmapImage();
bitImage.SetSource(fileStream);
bitImage.DecodePixelType = DecodePixelType.Physical;
bitImage.CreateOptions = BitmapCreateOptions.BackgroundCreation;
bitImage.CreateOptions = BitmapCreateOptions.DelayCreation;
double dblRation = (double)bitImage.PixelWidth / bitImage.PixelHeight;
//if (bitImage.PixelWidth > bitImage.PixelHeight)
//{
// bitImage.DecodePixelWidth = 200;
// bitImage.DecodePixelHeight = 200 / (int)dblRation;
//}
//else
//{
// bitImage.DecodePixelHeight = 200;
// bitImage.DecodePixelWidth = (int)(200 * dblRation);
//}
attachedImage.Source = bitImage;
GC.Collect();
GC.WaitForPendingFinalizers();
fileStream.Flush();
fileStream.Dispose();
fileStream.Close();
bitImage = null;
fileStream = null;
fileBytes = null;
sp.Children.Add(attachedImage);
Debug.WriteLine("[ApplicationCurrentMemoryUsage](MB) : \n" + (DeviceStatus.ApplicationCurrentMemoryUsage / 1024 / 1024));
}
}
It is just demo code. When I pick first image it will rise from 8 MB to 37 MB usage.But in real application it will rise from 64 MB to 112 MB.
Please help me to sort it out.
Related
How can I upload a PDF file to host via C# so that it is available for download via an adroid app? This is what I have tried, but it does not work. What am I doing wrong?
static void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
string fileName = ((FTPsetting)e.Argument).Filename;
string fullName = ((FTPsetting)e.Argument).FullName;
string username = ((FTPsetting)e.Argument).Username;
string password = ((FTPsetting)e.Argument).Password;
string server = ((FTPsetting)e.Argument).Server;
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(new Uri(string.Format("{0}/{1}", server, fileName)));
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential(username, password);
Stream ftpstream = request.GetRequestStream();
FileStream fs = File.OpenRead(fullName);
byte[] buffer = new byte[1024];
double total = (double)fs.Length;
int byteread = 0;
double read = 0;
do
{
if (!backgroundWorker.CancellationPending)
{
byteread = fs.Read(buffer, 0, 1024);
ftpstream.Write(buffer, 0, byteread);
read += (double)byteread;
double percontage = read / total * 100;
backgroundWorker.ReportProgress((int)percontage);
}
}
while (byteread != 0);
fs.Close();
ftpstream.Close();
}
static void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
Console.WriteLine("Completed" + e.ProgressPercentage + "%");
}
I used the UnZipper class from this (How to unzip files in Windows Phone 8) post in my app for zips with images, but in some rare cases it gives me this error:
A first chance exception of type 'System.OutOfMemoryException' occurred in System.Windows.ni.dll System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown. at System.Windows.Application.GetResourceStreamInternal(StreamResourceInfo zipPackageStreamResourceInfo, Uri resourceUri) at System.Windows.Application.GetResourceStream(StreamResourceInfo zipPackageStreamResourceInfo, Uri uriResource) at ImperiaOnline.Plugins.UnZipper.GetFileStream(String filename) at ImperiaOnline.Plugins.IOHelpers.unzip(String zipFilePath, String zipDestinationPath)
The device has more then twice needed free memory. Can somebody help me with this. Here is my code:
public static void unzip(string zipFilePath,string zipDestinationPath) {
using (IsolatedStorageFile isolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
var dirNames = isolatedStorage.GetDirectoryNames(zipDestinationPath);
bool doesFolderExists = (dirNames.Length > 0) ? true : false;
if (!doesFolderExists)
{
Debug.WriteLine("Folder does not exists");
isolatedStorage.CreateDirectory(zipDestinationPath);
}
try
{
using (IsolatedStorageFileStream zipFile = isolatedStorage.OpenFile(zipFilePath, FileMode.Open, FileAccess.ReadWrite))
{
UnZipper unzip = new UnZipper(zipFile);
bool isModuleFolderDeleted = false;
foreach (string currentFileAndDirectory in unzip.FileNamesInZip())
{
string[] fileLocations = currentFileAndDirectory.Split('/');
string prefix = zipDestinationPath + '/';
int locationsCount = fileLocations.Length;
string fileName = fileLocations.Last();
string currentPath = prefix;
for (int i = 0; i < locationsCount - 1; i++)
{
dirNames = isolatedStorage.GetDirectoryNames(currentPath + fileLocations[i]);
doesFolderExists = (dirNames.Length > 0) ? true : false;
if (!doesFolderExists)
{
isolatedStorage.CreateDirectory(currentPath + fileLocations[i]);
if (i == 2)
{
isModuleFolderDeleted = true;
}
}
else if (i == 2 && !isModuleFolderDeleted)
{
Debug.WriteLine(currentPath + fileLocations[i] + " is deleted and recreated");
DeleteDirectoryRecursively(isolatedStorage, currentPath + fileLocations[i]);
isolatedStorage.CreateDirectory(currentPath + fileLocations[i]);
isModuleFolderDeleted = true;
}
currentPath += fileLocations[i] + '/';
}
var newFileStream = isolatedStorage.CreateFile(currentPath + fileName);
byte[] fileBytes = new byte[unzip.GetFileStream(currentFileAndDirectory).Length];
unzip.GetFileStream(currentFileAndDirectory).Read(fileBytes, 0, fileBytes.Length);
unzip.GetFileStream(currentFileAndDirectory).Close();
try
{
newFileStream.Write(fileBytes, 0, fileBytes.Length);
}
catch (Exception ex)
{
Debug.WriteLine("FILE WRITE EXCEPTION: " + ex);
newFileStream.Close();
newFileStream = null;
zipFile.Close();
unzip.Dispose();
}
newFileStream.Close();
newFileStream = null;
}
zipFile.Close();
unzip.Dispose();
}
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
isolatedStorage.DeleteFile(zipFilePath);
}
}
This error appears here:
var newFileStream = isolatedStorage.CreateFile(currentPath + fileName);
byte[] fileBytes = new byte[unzip.GetFileStream(currentFileAndDirectory).Length]; unzip.GetFileStream(currentFileAndDirectory).Read(fileBytes, 0, fileBytes.Length);
unzip.GetFileStream(currentFileAndDirectory).Close();
I debugged it and it fails on
byte[] fileBytes = new byte[unzip.GetFileStream(currentFileAndDirectory).Length];
I checked GetFileStream method
public Stream GetFileStream(string filename)
{
if (fileEntries == null)
fileEntries = ParseCentralDirectory(); //We need to do this in case the zip is in a format Silverligth doesn't like
long position = this.stream.Position;
this.stream.Seek(0, SeekOrigin.Begin);
Uri fileUri = new Uri(filename, UriKind.Relative);
StreamResourceInfo info = new StreamResourceInfo(this.stream, null);
StreamResourceInfo stream = System.Windows.Application.GetResourceStream(info, fileUri);
this.stream.Position = position;
if (stream != null)
return stream.Stream;
return null;
}
It throws OutOfMemory exception on this row:
StreamResourceInfo stream = System.Windows.Application.GetResourceStream(info, fileUri);
This is the method:
Getting the Length of the files give 0 already.
public void DownloadFtpContent(object sender ,string file, string filesdirectories,string fn)
{
try
{
BackgroundWorker bw = sender as BackgroundWorker;
string filenameonly = Path.GetFileName(file);
string ftpdirectories = Path.Combine(ftpcontentdir, filesdirectories);
string fileurl = "ftp://" + file;
FtpWebRequest reqFTP;
reqFTP = (FtpWebRequest)FtpWebRequest.Create(fileurl);
reqFTP.Credentials = new NetworkCredential(UserName, Password);
reqFTP.UseBinary = true;
reqFTP.UsePassive = true;
reqFTP.KeepAlive = true;
reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
reqFTP.Proxy = null;
FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
Stream responseStream = response.GetResponseStream();
if (!Directory.Exists(ftpdirectories))
{
Directory.CreateDirectory(ftpdirectories);
}
FileStream writeStream = new FileStream(ftpdirectories + "\\" + filenameonly, FileMode.Create);
string fnn = ftpdirectories + "\\" + filenameonly;
int Length = 2048;
Byte[] buffer = new Byte[Length];
int bytesRead = responseStream.Read(buffer, 0, Length);
long FileSize = new FileInfo(fnn).Length;
string FileSizeDescription = GetFileSize(FileSize);
while (bytesRead > 0)
{
writeStream.Write(buffer, 0, bytesRead);
bytesRead = responseStream.Read(buffer, 0, Length);
string SummaryText = String.Format("Transferred {0} / {1}", GetFileSize(bytesRead), FileSizeDescription);
bw.ReportProgress((int)(((decimal)bytesRead / (decimal)FileSize) * 100), SummaryText);
}
writeStream.Close();
response.Close();
}
catch (WebException wEx)
{
//MessageBox.Show(wEx.Message, "Download Error");
}
catch (Exception ex)
{
//MessageBox.Show(ex.Message, "Download Error");
}
}
}
Already on this line the result is 0:
long FileSize = new FileInfo(fnn).Length;
In fnn i have: c:\myftpdownloads\root\Images\CB 967x330.jpg
Why the result of the Length is 0 ?
And the file is not 0kb size.
EDIT
This is how i'm calling the download method from backgroundworker dowork event:
private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i < numberOfFiles.Count; i++)
{
int fn = numberOfFiles[i].IndexOf(txtHost.Text, 0);
string fn1 = numberOfFiles[i].Substring(txtHost.Text.Length + 1, numberOfFiles[i].Length - (txtHost.Text.Length + 1));
string dirs = Path.GetDirectoryName(fn1);
string filename = Path.GetFileName(fn1);
ftpProgress1.DownloadFtpContent(sender,numberOfFiles[i], dirs, filename);
}
}
In fnn i have: c:\myftpdownloads\root\Images\CB 967x330.jpg Why the result of the Length is 0 ?
It doesn't really matter why the result of the length is 0. It does matter that you divide that number by 0 without any protection.
Just check before you divide:
if( FileSize != 0 ){...}
I followed the examples here: http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj662940%28v=vs.105%29.aspx
I made the live preview and stuff work, but how can I take a picture? This is what i tried:
private PhotoCaptureDevice _photoCaptureDevice = null;
string strImageName = "IG_Temp";
private NokiaImagingSDKEffects _cameraEffect = null;
private MediaElement _mediaElement = null;
private CameraStreamSource _cameraStreamSource = null;
private Semaphore _cameraSemaphore = new Semaphore(1, 1);
MediaLibrary library = new MediaLibrary();
private async void ShutterButton_Click(object sender, RoutedEventArgs e)
{
if (_cameraSemaphore.WaitOne(100))
{
await _photoCaptureDevice.FocusAsync();
_cameraSemaphore.Release();
CameraCaptureSequence seq = _photoCaptureDevice.CreateCaptureSequence(1);
await seq.StartCaptureAsync();
MemoryStream captureStream1 = new MemoryStream();
// Assign the capture stream.
seq.Frames[0].CaptureStream = captureStream1.AsOutputStream();
try
{
// Set the position of the stream back to start
captureStream1.Seek(0, SeekOrigin.Begin);
// Save photo as JPEG to the local folder.
using (IsolatedStorageFile isStore = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream targetStream = isStore.OpenFile(strImageName, FileMode.Create, FileAccess.Write))
{
// Initialize the buffer for 4KB disk pages.
byte[] readBuffer = new byte[4096];
int bytesRead = -1;
// Copy the image to the local folder.
while ((bytesRead = captureStream1.Read(readBuffer, 0, readBuffer.Length)) > 0)
{
targetStream.Write(readBuffer, 0, bytesRead);
}
}
}
}
finally
{
// Close image stream
captureStream1.Close();
}
// Navigate to the next page
Dispatcher.BeginInvoke(() =>
{
NavigationService.Navigate(new Uri("/Edit.xaml?name=" + strImageName, UriKind.Relative));
});
}
}
But I will get an error:
System.InvalidOperationException
in line: await seq.StartCaptureAsync();
What am I doing wrong?
I want to upload my recorded file to skydrive and I am using these codes
For recording;
void StopRecording()
{
// Get the last partial buffer
int sampleSize = microphone.GetSampleSizeInBytes(microphone.BufferDuration);
byte[] extraBuffer = new byte[sampleSize];
int extraBytes = microphone.GetData(extraBuffer);
// Stop recording
microphone.Stop();
// Create MemoInfo object and add at top of collection
int totalSize = memoBufferCollection.Count * sampleSize + extraBytes;
TimeSpan duration = microphone.GetSampleDuration(totalSize);
MemoInfo memoInfo = new MemoInfo(DateTime.UtcNow, totalSize, duration);
memoFiles.Insert(0, memoInfo);
// Save data in isolated storage
using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream stream = storage.CreateFile("/shared/transfers/" + memoInfo.FileName))
{
// Write buffers from collection
foreach (byte[] buffer in memoBufferCollection)
stream.Write(buffer, 0, buffer.Length);
// Write partial buffer
stream.Write(extraBuffer, 0, extraBytes);
}
}
}
For Uploading file;
async void OnSaveButtonClick(object sender, RoutedEventArgs args)
{
Button btn = sender as Button;
MemoInfo clickedMemoInfo = btn.Tag as MemoInfo;
memosListBox.SelectedItem = clickedMemoInfo;
if (this.client == null)
{
gridSingin.Visibility = Visibility.Visible;
memosListBox.Visibility = Visibility.Collapsed;
}
else
{
using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication())
{
using (var fileStream = store.OpenFile(clickedMemoInfo.FileName, FileMode.Open, FileAccess.Read, FileShare.Read))
{
LiveOperationResult res = await client.BackgroundUploadAsync("me/skydrive",
new Uri("/shared/transfers/" + clickedMemoInfo.FileName, UriKind.Relative),
OverwriteOption.Overwrite
);
InfoText.Text = "File " + clickedMemoInfo.FileName + " uploaded";
}
}
}
}
But I am gettin error in here
LiveOperationResult res = await client.BackgroundUploadAsync("me/skydrive", new Uri("/shared/transfers/" + clickedMemoInfo.FileName, UriKind.Relative), OverwriteOption.Overwrite);
I am getting this error;
An unhandled exception of type 'System.Reflection.TargetInvocationException' occurred in System.Windows.ni.dll
Could you help me, please?
You cannot have the file open when trying to upload. Try doing this.
using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication())
{
if (store.FileExists(fileName))
{
client.BackgroundUploadAsync("me/skydrive", new Uri(fileName, UriKind.Relative),
OverwriteOption.Overwrite);
}
}