我有一个winforms应用程序,用户可以从可用图像列表中选择图像,相应的图像显示在PictureBox中。图像可以非常大,最小10MB。这显然会使图像加载时UI的其余部分无响应。所以我想到使用以下代码在单独的线程上加载图像:
private void LoadImage()
{
// loadViewerThread is a Thread object
if (loadViewerThread != null && loadViewerThread.IsAlive)
{
loadViewerThread.Abort(); // Aborting the previous thread if the user has selected another image
}
loadViewerThread = new Thread(SetViewerImage);
loadViewerThread.Start();
}
SetViewerImage函数如下:
private void SetViewerImage()
{
if (pictureBox1.Image != null)
pictureBox1.Image.Dispose();
pictureBox1.Image = new Bitmap(/*Some stream*/);
}
此后图像平滑加载,也可以访问UI。 但是如果用户在图像集之间移动得非常快,则会出现一个大的红色X标记。发生这种情况是因为我在 SetViewerImage 中调用了Dispose。
我已经为PictureBox分配了一个ErrorImage,但在这种情况下从不显示ErrorImage。
问题:
答案 0 :(得分:0)
您需要在UI线程中操纵控件。您可以使用其他线程中的Control.Invoke()来执行此操作。
最大的瓶颈是从流中创建图像,因此您应该能够像这样重新组织方法以保持UI线程的释放:
private void SetViewerImage()
{
Bitmap image = new Bitmap(/* Some stream*/);
pictureBox1.Invoke(new Action(() =>
{
if (pictureBox1.Image != null)
{
pictureBox1.Image.Dispose();
pictureBox1.Image = null; // This might help? Only add if it does.
}
pictureBox1.Image = image;
}));
}