C# 当从后台线程更新时,UI会略微冻结

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

我有一个Winform和4个PictureBox控件,每个控件将包含不同的图像。这个过程是:

引发一个事件x,该事件中的eventargs包含每个映像(4)的文件名,以此类推(文件存在等)。然后,我必须更新UI

我通常使用Invoke:

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