0

I am using a loop to place images in my canvas, there is a method that needs to check if each looped images have an attribute that is stored in a JSON file.

the checkImage method works fine outside the loop, but when I place it in the loop it gives this error:

"Access denied, file is used by another process"

Since the method gets called for every image created by the loop I guess that I need to close the JSON file after its serialized or something, but how?

The loop:

 while (i < blauw)
                {
                    checkImage(i); //checks if it has the attribute or not
                    ImageBrush brush = new ImageBrush();
                    Button Btn = new Button();
                    Uri uri = new Uri("ms-appx://Blijfie/images/" + selected + "/" + blauwpics[i]);
                    BitmapImage imgSource = new BitmapImage(uri);
                    brush.ImageSource = imgSource;
                    Btn.Background = brush;
                    Btn.Width = 200;
                    Btn.Height = 200;

                    if (i >= 5 && i < 10)
                    {
                        Canvas.SetTop(Btn, marginTop);
                        Canvas.SetLeft(Btn, marginLeft2);
                        marginLeft2 = marginLeft2 + 250;
                    }
                    else if (i < 6)
                    {
                        Canvas.SetLeft(Btn, marginLeft);
                        marginLeft = marginLeft + 250;

                    }
                    else if (i >= 10)
                    {
                        Canvas.SetTop(Btn, marginTop2);
                        Canvas.SetLeft(Btn, marginLeft3);
                        marginLeft3 = marginLeft3 + 250;
                    }
                    main.Children.Add(Btn);
                    i++;

                }

CheckImage method:

 private async void checkImage(int id) {
                    var foldertest = ApplicationData.Current.TemporaryFolder;
                    var files = await foldertest.GetFilesAsync();
                    var desiredFile = files.FirstOrDefault(x => x.Name == "Dierendb.json");
                    var textContent = await FileIO.ReadTextAsync(desiredFile);

                    var result = JsonConvert.DeserializeObject<List<Dier>>(textContent);

                    id++;

                    if (result[id].PathDier.Equals(""))
                    {
                        //do this
                    }
                    else
                    {
                        //do that
                    }


                    string dierenlijst = JsonConvert.SerializeObject(result, Formatting.Indented);
                    await Windows.Storage.FileIO.WriteTextAsync(desiredFile, dierenlijst, Windows.Storage.Streams.UnicodeEncoding.Utf8);

    }
Yoshi
  • 231
  • 1
  • 5
  • 13
  • 1
    What loop? Also, `async void` is a famously bad idea. – David Mar 25 '16 at 14:33
  • Added the loop, didn't think it was necessary. Why is it a bad idea? There is probably a better way to do this, but can't think of 1. – Yoshi Mar 25 '16 at 14:37
  • 1
    Because `void` can't be awaited. Note that in the loop you're not awaiting the method. If multiple calls to the method are simultaneously trying to write to the same file, then the file system is going to refuse that. – David Mar 25 '16 at 14:40
  • 3
    Stephen Cleary explains it well. https://msdn.microsoft.com/en-us/magazine/jj991977.aspx His blog is very good about all things async http://blog.stephencleary.com/2012/02/async-and-await.html – HebeleHododo Mar 25 '16 at 14:40

2 Answers2

4

Return the Task instead of void. And await for it complete in loop like this.

  while (i < blauw)
                {
                    var bool= await checkImage(i); //checks if it has the attribute or not
                    ImageBrush brush = new ImageBrush();
                    Button Btn = new Button();
                    Uri uri = new Uri("ms-appx://Blijfie/images/" + selected + "/" + blauwpics[i]);
                    BitmapImage imgSource = new BitmapImage(uri);
                    brush.ImageSource = imgSource;
                    Btn.Background = brush;
                    Btn.Width = 200;
                    Btn.Height = 200;

                    if (i >= 5 && i < 10)
                    {
                        Canvas.SetTop(Btn, marginTop);
                        Canvas.SetLeft(Btn, marginLeft2);
                        marginLeft2 = marginLeft2 + 250;
                    }
                    else if (i < 6)
                    {
                        Canvas.SetLeft(Btn, marginLeft);
                        marginLeft = marginLeft + 250;

                    }
                    else if (i >= 10)
                    {
                        Canvas.SetTop(Btn, marginTop2);
                        Canvas.SetLeft(Btn, marginLeft3);
                        marginLeft3 = marginLeft3 + 250;
                    }
                    main.Children.Add(Btn);
                    i++;

               }

Private Task<bool> CheckImage(int i)
{
Yourcode
Return true;
}
Archana
  • 3,213
  • 1
  • 15
  • 21
1

In this answer you can find good explanation difference between returning void and Task. In you case you should change return type to Task and await it in your loop

Community
  • 1
  • 1