我有一个 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*/);
}
在此之后图像加载顺利,用户界面也可以访问。 但是,如果用户在图像集之间移动得非常快,则会出现一个大的红色 X 标记。发生这种情况是因为我在 SetViewerImage 中调用了 Dispose。
我已将 ErrorImage 分配给 PictureBox,但在这种情况下从未显示该 ErrorImage。
问题:
- 我的线程实现有什么问题吗?为什么 图片被处置?
- 有什么方法可以显示不同的 ErrorImage 而不是 红色的 X?
最佳答案
您需要在 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;
}));
}
关于c# - PictureBox 分配的 ErrorImage 在错误地处理其图像后未显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37395191/