如何在启动新线程时停止线程?

时间:2018-01-10 18:40:54

标签: c# multithreading lockbits

我改进了我创建的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;

根据我从研究中收集的内容,我认为这是因为该方法在完成第一次之前第二次运行,因此尝试解锁已解锁的数据。

如果这是正确的,那么在创建新线程时如何中止正在运行的线程?最后一次电话总是很重要的

1 个答案:

答案 0 :(得分:0)

  1. 在开始新通话之前,请等待现有通话完成。你可以通过简单地使用lock区域来做到这一点。这解决了正确性问题。也许使用Task使每个计算更容易进入Task.Run。生成的Task对象是该计算的句柄,可用于等待它完成。
  2. 如果要加快完成不再需要的旧计算运行,请添加取消机制。在这里,您可以使用volatile bool cancel = false;。将其设置为true以取消。在你的并行循环中(可能在其他地方),定期检查该布尔变量,如果找到它true则终止。您还可以使用CancellationTokenSource