0

我在 Downloader 类中有 2 个异步下载。基本上,代码首先发出一个简单的基于 http 的 API 请求以获取一些包含 url 的数据,然后使用此 url 下载图像 - 最后一个函数调用 - Test(adImage) 尝试将 UIImage 传递回主函数ViewController 类,以便它可以使用下载的图像更新 UIImageView。当我尝试这样做时,我在该行收到 ArgumentNullException

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

我认为这是因为我需要使用主 UI 线程来更新主 VC,并且不能从运行在另一个异步线程上的这个对象来完成。如果我把测试功能拿出来,一切都运行良好并且图像被下载——只是没有用于任何事情。

如何将图像传递回 mainVC 并让它更新主 UI 线程上的图像?

(这与我之前提出的一个问题有关,但我认为我之前完全是在吠叫错误的树,所以我觉得以不同的方式重新表达问题更好)。

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);
        }

    ....
}
4

1 回答 1

0

该死的,在为此工作了几个小时后,我终于在发布后几分钟弄明白了。

就像包装 UI 代码一样简单:

InvokeOnMainThread (delegate {  
    // UI Update code here... 
});
于 2013-07-14T09:56:43.567 回答