Hello fellow programmers, i'm beginner to async programming I confess. Today I have ran some tests with async operations and found something rather interesting:
When I call await myStorageFolder.GetFilesAsync();
My async function gets frozen and doesn't throw any exception, but the task never completes, although, if I call myStorageFolder.GetFilesAsync().AsTask().Result;
instead, the command returns the data as expected, almost instantly (just as fast as winforms Directory.GetFiles())
Now, my problem here is, writing these lines:
var myFileStream = await myFile.OpenAsync(Windows.Storage.FileAccessMode.Read);
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(myFileStream);
In this case the await works very well on OpenAsync, but not in the BitmapDecoder.CreateAsync (which freezes), and, casting it to a Task and calling its "Result" property doesn't make it any faster.
So this is my question, what is the best approach to get around with this async programming and, whats the difference between calling (await) and (AsTask().Result), if, theoretically both will run "synchronously" in the async thread?
EDIT: Here is my function: Edit2: Translated my variable names to english
private async Task ExecuteComparatorAsync(StorageFolder folder)
{
_cancel = false;
Progress = 0;
Status = "Image comparator started.";
List<ImageData> ImagesToCheck = new List<ImageData>();
Status = "Searching Images...";
// if I use await on the next line, the whole function becomes irresponsive and will never return
IReadOnlyList<StorageFile> Files = folder.GetFilesAsync(Windows.Storage.Search.CommonFileQuery.DefaultQuery).AsTask().Result;
Status = "Let me see these images...";
foreach(StorageFile f in Files)
{
try
{
ImageData iData = await GetImageData(f);
ImagesToCheck.Add(iData);
}
catch (Exception s) {
String j = s.Message;
}
}
Status = "Got it.";
List<String> RepetedPaths = new List<String>();
for (int i = 0; i < ImagesToCheck.Count; i++)
{
Status = "Comparing images " + i + "/" + ImagesToCheck.Count;
for (int j = 0; j < ImagesToCheck.Count; j++)
{
if (_cancel)
return;
Boolean IsImageIRepeated = false;
Double Difference = await Compare(ImagesToCheck[i], ImagesToCheck[j]);
if (Difference < MinDiff)
{
String repeatedImage = String.Empty;
if (ImagesToCheck[i].Size > ImagesToCheck[j].Size)
{
repeatedImage = ImagesToCheck[j].Path.Path;
Debug.WriteLine("Duplicate: {0}", ImagesToCheck[j].Path.Path);
}
else
{
IsImageIRepeated = true;
repeatedImage = ImagesToCheck[i].Path.Path;
Debug.WriteLine("Duplicate: {0}", ImagesToCheck[j].Path.Path);
}
RepeatedPaths.Add(repeatedImage);
}
if (IsImageIRepeated)
break;
}
Progress = (i * 100) / ImagesToCheck.Count;
}
Status = String.Format("Done. {0} repeated images found.", Repetidas.Count);
Finished = true;
}
Here is my major problem:
async static Task<WriteableBitmap> LoadImage(StorageFile myFile, UInt32 Width, UInt32 Height)
{
var fStream = await myFile.OpenAsync(Windows.Storage.FileAccessMode.Read);
try
{
// The next line interrupts my entire operation.
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(fStream);
// AsTask().Result doesn't work either;
// No exceptions are thrown here.
InMemoryRandomAccessStream ras = new InMemoryRandomAccessStream();
BitmapEncoder enc = await BitmapEncoder.CreateForTranscodingAsync(ras, decoder);
enc.BitmapTransform.ScaledHeight = Height;
enc.BitmapTransform.ScaledWidth = Width;
BitmapBounds bounds = new BitmapBounds();
bounds.Height = Height;
bounds.Width = Width;
bounds.X = 0;
bounds.Y = 0;
enc.BitmapTransform.Bounds = bounds;
try
{
await enc.FlushAsync();
}
catch (Exception ex)
{
string s = ex.ToString();
}
WriteableBitmap bImg = new WriteableBitmap((int)Width, (int)Height);
await bImg.SetSourceAsync(ras);
return bImg;
}
catch (Exception e)
{
Debug.WriteLine(e.Message);
throw new Exception("This file is maybe, not an image at all...");
}
}
Typical case of deadlock due to calling Result
or Wait
somewhere. Audit your entire code to remove calls to those deadlock-prone functions. Or, call them in a deadlock-safe way.