0

I have 2 asynchronous downloads in a Downloader class. Basically the code first makes a simple http based API request to get some data containing a url, and then uses this url to download an image - the last function call - Test(adImage) tries to pass the UIImage back to a function in the main ViewController class, so that it can update a UIImageView with the downloaded image. When I try to do this, I get an ArgumentNullException at the line

string result = System.Text.Encoding.UTF8.GetString (e.Result);

I think this is because I need to use the main UI thread to update the main VC, and can't do it from this object running on another asynchronous thread. If I take the Test function out, everything runs fine and the image is downloaded - just not used for anything.

How do I pass the image back to the mainVC and get it to update the image on the main UI thread?

(This is related to a question I asked before, but I think I was totally barking up the wrong tree before, so I felt it better to re-express the problem in the different way).

public class Downloader : IImageUpdated {

        UIImage adImage;
        Manga5ViewController mainVC;

        public void DownloadWebData(Uri apiUrl, Manga5ViewController callingVC)
        {
            mainVC = callingVC;
            WebClient client = new WebClient();
            client.DownloadDataCompleted += DownloadDataCompleted;
            client.DownloadDataAsync(apiUrl);
        }

        public void DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
        {
            string result = System.Text.Encoding.UTF8.GetString (e.Result);
            string link = GetUri(result);
            Console.WriteLine (link);
            downloadImage(new Uri (link));
        }

        public void downloadImage (Uri imageUri) {

            var tmp_img = ImageLoader.DefaultRequestImage (imageUri, this);
            if (tmp_img != null)
            {
                adImage = tmp_img;
                Console.WriteLine ("Image already cached, displaying");
                Console.WriteLine ("Size: " + adImage.Size);
                mainVC.Test (adImage);
            }
            else
            {
                adImage = UIImage.FromFile ("Images/downloading.jpg");
                Console.WriteLine ("Image not cached.  Using placeholder.");
            }
        }

        public void UpdatedImage (System.Uri uri) {
            adImage = ImageLoader.DefaultRequestImage(uri, this);
            Console.WriteLine ("Size: " + adImage.Size);
            mainVC.Test (adImage);
        }

    ....
}
Nande
  • 637
  • 1
  • 7
  • 18

1 Answers1

0

Damn, after working on this for hours, I finally figured it out a few minutes after posting this.

It was as simple as wrapping the UI code like so:

InvokeOnMainThread (delegate {  
    // UI Update code here... 
});
Nande
  • 637
  • 1
  • 7
  • 18