【发布时间】:2016-07-06 07:58:58
【问题描述】:
我正在做一个项目,我需要在已经存在的图像(我在程序的开头定义)上绘制从套接字接收的图像块(作为位图),并显示它在PictureBox-换句话说,每次我收到一个新块时更新图像。
为了异步执行此操作,我使用Thread 从Socket 读取数据并进行处理。
这是我的代码:
private void MainScreenThread() {
ReadData();
initial = bufferToJpeg(); //full screen first shot.
pictureBox1.Image = initial;
while (true) {
int pos = ReadData();
int x = BlockX();
int y = BlockY();
Bitmap block = bufferToJpeg(); //retrieveing the new block.
Graphics g = Graphics.FromImage(initial);
g.DrawImage(block, x, y); //drawing the new block over the inital image.
this.Invoke(new Action(() => pictureBox1.Refresh())); //refreshing the picturebox-will update the intial;
}
}
private Bitmap bufferToJpeg()
{
return (Bitmap)Image.FromStream(ms);
}
我遇到了一个错误
对象当前正在其他地方使用
在Graphics 创建线上
Graphics g = Graphics.FromImage(initial);
我没有使用任何其他线程或其他东西来访问位图..所以我不确定这里有什么问题..
如果有人能启发我,我将非常感激。
谢谢。
【问题讨论】:
-
您刚刚发现 PictureBox 和 Bitmap 类都不是线程安全的。幸运的是,Bitmap 类有一个内置的诊断功能,当您在 PictureBox 重新绘制自身的同时使用 Graphics.FromImage() 时会出现 kaboom。非常随机,就像线程竞赛错误总是如此。您需要调用更多代码,包括 Graphics.FromImage 和 DrawImage。或者创建你自己的线程安全的 PictureBox 类,它的 OnPaint() 覆盖需要获取一个你也在这个方法中获取的锁。
-
你可能会很快遇到
OutOfMemoryException,你需要在每个循环中处理block,并在完成后处理g。
标签: c# multithreading sockets bitmap