C# 当从后台线程更新时,UI会略微冻结
我有一个Winform和4个PictureBox控件,每个控件将包含不同的图像。这个过程是: 引发一个事件x,该事件中的eventargs包含每个映像(4)的文件名,以此类推(文件存在等)。然后,我必须更新UI 我通常使用Invoke:C# 当从后台线程更新时,UI会略微冻结,c#,multithreading,user-interface,delegates,C#,Multithreading,User Interface,Delegates,我有一个Winform和4个PictureBox控件,每个控件将包含不同的图像。这个过程是: 引发一个事件x,该事件中的eventargs包含每个映像(4)的文件名,以此类推(文件存在等)。然后,我必须更新UI 我通常使用Invoke: Invoke((ThreadStart)delegate() { picBig.Image = new Bitmap(strImageBig); picLittle1.Image = new Bitmap(saLittle[0]); pi
Invoke((ThreadStart)delegate()
{
picBig.Image = new Bitmap(strImageBig);
picLittle1.Image = new Bitmap(saLittle[0]);
picLittle2.Image = new Bitmap(saLittle[1]);
picLittle3.Image = new Bitmap(saLittle[2]);
});
// saLittle[] is a string array, contains, filenames: "image1.jpg"
但当这个执行时,表单会冻结一段时间,大约500毫秒,我知道这是一个很小的间隔,但很明显,然后应用程序会正常运行
我试图找出“UI冻结”的原因,然后,经过研究,我发现了BeginInvoke。现在,我的代码如下所示:
BeginInvoke((MethodInvoker)delegate
{
picBig.Image = new Bitmap(strImageBig);
picLittle1.Image = new Bitmap(saLittle[0]);
picLittle2.Image = new Bitmap(saLittle[1]);
picLittle3.Image = new Bitmap(saLittle[2]);
});
这要快一点。但用户界面仍然冻结了200~300毫秒
在我读过的文章中,他们说BeginInvoke比Invoke更好
代码运行正常,逻辑或其他方面没有问题。我只是想知道为什么会这样。我不想让这个疑问变得模糊不清。这个项目已经完成了。希望这对其他人有用
也许这不是正确的方法。我知道有很多方法可以从后台线程更新UI,但是还有其他方法可以使更新速度更快吗
或者,你认为图像加载是原因吗?有没有其他方法可以更快地加载图像
提前谢谢
但当这个执行时,表单会冻结一段时间,大约500毫秒,我知道这是一个很小的间隔,但很明显,然后应用程序会正常运行
最终,UI线程需要实际更新图像。在UI线程上生成和更新图像时,这将导致(短)延迟。这是因为您实际上是在UI线程上从磁盘加载图像,同时设置控件的内容。使用文件路径调用
位图
构造函数将转到硬盘并将图像加载到内存中
Invoke
和BeginInvoke
将在创建控件的线程上运行您提供的委托,该线程很可能是UI线程
…但是有没有其他方法可以加快更新速度
在后台线程中加载图像,当它们实际加载时,调用图像并将其设置到控件中
var big = new Bitmap(strImageBig);
var little1 = new Bitmap(saLittle[0]);
var little2 = new Bitmap(saLittle[1]);
var little3 = new Bitmap(saLittle[2]);
Invoke((ThreadStart)delegate()
{
picBig.Image = big;
picLittle1.Image = little1;
picLittle2.Image = little2;
picLittle3.Image = little3;
});