2

I'm trying to download some pictures from the internet Asynchronously. I've built the GetImageBitmapFromUrl method as following

async Task<Bitmap> GetImageBitmapFromUrl(string url)
{
    Bitmap imageBitmap = null;
    try
    {
        using (var webClient = new WebClient())
        {
            var imageBytes = await webClient.DownloadStringTaskAsync(url);
            if (imageBytes != null && imageBytes.Length > 0)
            {
                imageBitmap = BitmapFactory.DecodeByteArray(Encoding.ASCII.GetBytes(imageBytes), 0, imageBytes.Length);
            }
        }
    }
    catch
    {
        //Silence is gold.
    }
    return imageBitmap;
}

I'm now trying to call this method inside my setter

List<string> _pictures;
Bitmap[] imageBitmap;
int currentPic = 0;
ImageView gellaryViewer;
public List<string> pictures
{
    set
    {
        if (value.Count == 0)
        {
            gellaryViewer.Visibility = ViewStates.Gone;
        }
        else
        {
            gellaryViewer.Visibility = ViewStates.Visible;
            _pictures = value;
            currentPic = 0;
            imageBitmap = new Bitmap[value.Count];
            for (int i = 0; i < value.Count; i++)
                //The 'await' operator can only be used within an async method. Consider marking this method with the 'async' modifier and changing its return type to 'Task'.
                imageBitmap[i] = await GetImageBitmapFromUrl(value[i]);
            displayPic();
        }
    }
    get { return _pictures; }
}

But I'm getting this error
The 'await' operator can only be used within an async method. Consider marking this method with the 'async' modifier and changing its return type to 'Task'.

How can I mark the setter with the 'async' modifier?

Abozanona
  • 2,261
  • 1
  • 24
  • 60

2 Answers2

0

Check out the answer to this question: How to call an async method from a getter or setter?.

That being said, I would highly recommend moving the update functionality away from the property to a separate method. Properties are meant to provide the current state of things, not block indefinitely.

Community
  • 1
  • 1
aksu
  • 1,748
  • 1
  • 11
  • 15
0

Simple answer: You can't. All properties (both get and set) and synchronous. Keep it an async function and you're good.

Complex answer: You can, but it's ugly. Make the async function a private one, and call it from your set method. But since the set is synchronous, while the calling method is async , you'll have to make this call differently. Look at this SO post for various options.

This note this last option should only be used when you don't have any other option. Debugging might be hard and you might run into race conditions you don't want to happen.

Community
  • 1
  • 1
MarcoK
  • 6,090
  • 2
  • 28
  • 40