在异步图像下载后,将控制权交还给主UI线程以更新UI

本文关键字:UI 线程 更新 控制权 图像 异步 下载 | 更新日期: 2023-09-27 18:22:19

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

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

我想这是因为我需要使用主UI线程来更新主VC,而不能通过在另一个异步线程上运行的对象来完成。如果我去掉Test函数,一切都会正常运行,并且图像会被下载——只是不用于任何用途。

如何将图像传递回主VC,并让它更新主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);
        }
    ....
}

在异步图像下载后,将控制权交还给主UI线程以更新UI

该死,在做了几个小时之后,我终于在发布这篇文章几分钟后发现了它。

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

InvokeOnMainThread (delegate {  
    // UI Update code here... 
});