如何在VB.NET windows.forms.listbox中从webserver加载图像而不冻结UI [英] How to load images from webserver in VB.NET windows.forms.listbox without freezing UI

查看:74
本文介绍了如何在VB.NET windows.forms.listbox中从webserver加载图像而不冻结UI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将缩略图图像(mp3专辑封面图片)从网络服务器加载到vb.net Windows.Forms.Listbox中。我在.drawitem事件中这样做。只要有快速稳定的连接,这就可以工作。但是当下载以某种方式中断时,UI会冻结。所以我需要以某种方式做同步异步。



你们怎么会这样做?许多其他程序都是这样做的。



我正在考虑首先加载默认图像,然后在图像进入时更新列表框。这会有效吗?以及如何最好地实现这个?



我尝试过:



我尝试为每个.drawitem事件触发异步下载。但这导致了许多下载,同时冻结了UI。特别是在滚动时。

I am trying to load thumbnail images (mp3 album cover art) from a web server into a vb.net Windows.Forms.Listbox. I do this in the .drawitem event. This works as long as there is a fast and stable connection. But of course the UI freezes when the download is interrupted somehow. So I need to do this async somehow.

How would you guys go about this? Many many other programs out there do this.

I was thinking of loading a default image first and then updating the listbox as images come in. Would this be effective? And how best to implement this?

What I have tried:

I tried triggering an async download for every .drawitem event. But this resulted in many downloads at the same time, freezing the UI even more. Especially when scrolling.

推荐答案

另请参阅Gamma等人描述的代理模式四)。这种缓慢的图像加载被作为该模式背后的动机的一个例子。
Also look at the Proxy Pattern described by Gamma et al (the "Gang of Four"). Such slow loading of images was taken as an example for the motivation behind that pattern.


你可以拥有一个由阻塞队列/集合驱动的永久工作线程。例如,您可以向其提供URL,并允许您在输出中下载常规的非阻塞队列中的图像。这样,如果你没有这个线程的任务,它将花费零CPU时间,等待等待状态。



我在我的描述中所有这些文章简单的阻塞队列的线程通信和线程间调用 [ ^ ]。



您不需要使用我的队列类,因为您可以使用模板类 System.Collections.Concurrent.BlockingCollection< ;> ,如果您的目标.NET版本是4.0或更高版本:
BlockingCollection(T)类(System.Collections.Concurrent) [ ^ ]。



va我的文章的内容是详细说明操作原理和重要用例。



现在, Windows.Forms.ListBox 不是为了显示任何图像而设计的。如果你完全覆盖它的图形渲染,但它会完全失败使用这个类的目的。因此,您需要使用其他东西。一个可以显示图像的合适控件是 System.Windows.Forms.ListView

ListView类(System.Windows.Forms) [ ^ ]。



现在你可以使用UI而不会冻结。首先,您可以在列表视图中显示一些预定义的图像尚未就绪图像。下载图像后,您可以在预定义图像准备就绪时将其替换为已下载的图像。怎么样?您不能从非UI线程调用与UI相关的任何内容。相反,您需要使用 Invoke System.Windows.Threading的方法。 Dispatcher (对于Forms或WPF)或 System.Windows.Forms.Control (仅限表单)。



您将在我过去的答案中找到有关其工作原理和代码示例的详细说明:

Control.Invoke()与Control.BeginInvoke()

使用Treeview扫描仪和MD5的问题



另请参阅有关线程的更多参考资料:

主要的.NET事件线程

如何让keydown事件在不同的线程上运行i n vb.net

在启用禁用+多线程后控制事件未触发



-SA
You can have a permanently working thread which is driven by the blocking queue/collection. You feed, for example, URLs to it, and it gives you downloading images on output, in a regular, non-blocking queue. This way, if you don't have a task for this thread, it will spend zero CPU time, waiting in a wait state.

I described all this in my article Simple Blocking Queue for Thread Communication and Inter-thread Invocation[^].

You don't need to use my queue class, because you can use the template class System.Collections.Concurrent.BlockingCollection<>, if your target .NET version is 4.0 or later: BlockingCollection(T) Class (System.Collections.Concurrent)[^].

The value of my article is that explain the principles of operation and important use cases in detail.

Now, Windows.Forms.ListBox is not designed to show any images. If you completely override its graphic rendering, but it would defeat the purpose of using this class completely. Therefore, you need to use something else. One suitable control which can show image would be System.Windows.Forms.ListView:
ListView Class (System.Windows.Forms)[^].

Now you can use the UI without freezing. At first, you can show some predefined "image-is-not-yet-ready" image in the list view. As images are downloaded, you can replace the predefined images with the downloaded ones as they are ready. How? You cannot call anything related to UI from non-UI thread. Instead, you need to use the method Invoke or BeginInvoke of System.Windows.Threading.Dispatcher (for both Forms or WPF) or System.Windows.Forms.Control (Forms only).

You will find detailed explanation of how it works and code samples in my past answers:
Control.Invoke() vs. Control.BeginInvoke(),
Problem with Treeview Scanner And MD5.

See also more references on threading:
.NET event on main thread,
How to get a keydown event to operate on a different thread in vb.net,
Control events not firing after enable disable + multithreading.

—SA


这篇关于如何在VB.NET windows.forms.listbox中从webserver加载图像而不冻结UI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆