我改进了我创建的3d引擎的性能,引入了LockBits和并行处理。我有一个引擎类,使用以下方法更新结果的位图:
public void draw() {
clearbmp();
// locking bmp
BitmapData bitmapData = bmp.LockBits(new Rectangle(0, 0, W, H), ImageLockMode.ReadWrite, bmp.PixelFormat);
IntPtr FirstPixel = bitmapData.Scan0;
int bytes = Math.Abs(bitmapData.Stride) * H;
bpp = Bitmap.GetPixelFormatSize(bmp.PixelFormat) / 8;
rgbarray = new byte[bytes];
System.Runtime.InteropServices.Marshal.Copy(FirstPixel, rgbarray, 0, bytes);
int count = 0;
for (int k = 0; k < solidos.Count; k++)
{
if (solidos[k] != null && solidos[k].draw)
{
// separating faces of the solid into different threads
Parallel.ForEach(solidos[k].side, f =>
{
// ... do the operations...
});
}
}
// copy the array to the bitmap and unlock
System.Runtime.InteropServices.Marshal.Copy(rgbarray, 0, FirstPixel, bytes);
bmp.UnlockBits(bitmapData);
代码按预期运行以生成图像,但是当主程序要求它快速连续多次更新时,代码会失败,错误发生在 bmp.UnlockBits(bitmapData)中&#34; GDI +中的一般错误&#34;
根据我从研究中收集的内容,我认为这是因为该方法在完成第一次之前第二次运行,因此尝试解锁已解锁的数据。
如果这是正确的,那么在创建新线程时如何中止正在运行的线程?最后一次电话总是很重要的
答案 0 :(得分:0)
lock
区域来做到这一点。这解决了正确性问题。也许使用Task
使每个计算更容易进入Task.Run
。生成的Task
对象是该计算的句柄,可用于等待它完成。volatile bool cancel = false;
。将其设置为true
以取消。在你的并行循环中(可能在其他地方),定期检查该布尔变量,如果找到它true
则终止。您还可以使用CancellationTokenSource
。