Reputation: 141
Im writing a file to IsolatedStorageFile with an asynchronous call
async void Base64ToImage()
{
byte[] data;
using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream isfs = isf.OpenFile("image.p64", FileMode.Open, FileAccess.ReadWrite))
{
data = new byte[isfs.Length];
isfs.Read(data, 0, data.Length);
isfs.Close();
}
using (IsolatedStorageFileStream stream = isf.OpenFile("newReConvertedFile.png", FileMode.Create))
{
await stream.WriteAsync(data, 0, data.Length);
///////////////////The problem is here, how would i know when WriteAsync is complete to then fire the reload method?
//reLoadFile();
}
}
}
i need to know when that WriteAsync is complete to reload that file in another method, how would i go about doing that?
Edit:
Actually my first idea was to save the file to isostorage then sen the image uri to that file, but you can't set uri to isostorage for images or at least i couldn't get to display
My initial thought was to await the method call to reload the file but i get an error “??? does not return a task and cannot be awaited. Consider changing it to return” but I’m not sure how to go about doing this.
The idea here is to convert several images to Base64 (SQLite db), but then load only the selected ones, to display.
the reLoadFile method is as follows
async void reLoadFile()
{
byte[] newFile;
using (IsolatedStorageFile newFileLoc = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream newFileStream = newFileLoc.OpenFile("newReConvertedFile.png", FileMode.Open, FileAccess.ReadWrite))
{
newFile = new byte[newFileStream.Length];
newFileStream.Read(newFile, 0, newFile.Length);
newFileStream.Close();
var ms = new MemoryStream(newFile);
var image = new BitmapImage();
image.SetSource(ms);
theImage.Source = image;
}
}
}
I've been searching the posts but i couldn't fine a way to get it to work, because if i call it straight away i get an exception. What i need to do is open the file convert it from base64 to .png then load the .png file after it has been saved. If someone could help me out i would appreciate it.
Thanks Bob.
Upvotes: 3
Views: 4156
Reputation: 127593
1) reloadFile
does not need to be async
you only need to use that when you use the await
keyword inside the method
2) BaseTo64Image needs to be declared as async Task Base64ToImage()
otherwise the callers of Base64ToImage()
will not be able to tell when it finishes.
3) isfs.Read(data, 0, data.Length);
is bad, just because you requested data.Length
bytes does not mean you will get data.Length
read in, you need to check the int
read returns and loop or use CopyTo(Stream)
to copy to another stream.
4) (to actually answer your question) the keyword await
will stop the function from processing and wait till the function is complete. When you hit the await
keyword your Base64ToImage()
function will return at that point with a Task
representing the rest of the code in that function, it is up to you what you do with that Task
returned from the function.
Here is a simplified version of your code using all of the suggestions
async Task Base64ToImage()
{
using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
using (IsolatedStorageFileStream stream = isf.OpenFile("newReConvertedFile.png", FileMode.Create))
using (IsolatedStorageFileStream isfs = isf.OpenFile("image.p64", FileMode.Open, FileAccess.ReadWrite))
{
await isfs.CopyToAsync(stream);
}
await ReLoadFile();
}
async Task ReLoadFile()
{
using (IsolatedStorageFile newFileLoc = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream newFileStream = newFileLoc.OpenFile("newReConvertedFile.png", FileMode.Open, FileAccess.ReadWrite))
{
var ms = new MemoryStream();
var image = new BitmapImage();
await newFileStream.CopyToAsync(ms);
ms.Position = 0;
image.SetSource(ms);
theImage.Source = image;
}
}
}
However if that is all you are doing, and you are just using newReConvertedFile.png
as a temporary file you can simplify your code to
async Task Base64ToImage()
{
using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
using (IsolatedStorageFileStream isfs = isf.OpenFile("image.p64", FileMode.Open, FileAccess.ReadWrite))
{
var ms = new MemoryStream();
var image = new BitmapImage();
await isfs.CopyToAsync(ms);
ms.Position = 0;
image.SetSource(ms);
theImage.Source = image;
}
}
Upvotes: 4
Reputation: 456887
The WriteAsync
method is complete when its returned Task
completes.
To wait for the task to complete, just await
it:
await stream.WriteAsync(data, 0, data.Length);
// WriteAsync is complete.
Upvotes: 2
Reputation: 73492
Just call it in next line. await will wait asynchronously till WriteAsync
completes. That's what the beauty of "async/await" which lets you to write asynchronous code that looks synchronous.
using (IsolatedStorageFileStream stream = isf.OpenFile("newReConvertedFile.png", FileMode.Create))
{
await stream.WriteAsync(data, 0, data.Length);
reLoadFile();
}
Am I missing something?
Upvotes: 1