1

我正在构建一个桌面应用程序,它在绘图区域上打印一系列矩形。此应用程序是使用 MONO C# 构建的。

我使用普通的“FOR”循环没有问题,我得到了预期的结果。

当我使用正常的 FOR 循环时,流动是输出

在此处输入图像描述

当我使用正常的 Parallel.For 循环时,流动是输出

在此处输入图像描述

正如我们所看到的,其中一些矩形丢失了。

我正在使用 ConcurrentQueue 来保存创建的矩形并将相同的队列传递给其他函数以将其打印在绘图区域上。

以下是代码。

 public static void DrwaWall (DrawingArea drawArea, string compLevel)
    {
        house.Rectangle rect = new house.Rectangle ();
        house.DrawHouse DrawHouse = new house.DrawHouse ();
        ConcurrentQueue<house.Rectangle> WallHouseQ = new ConcurrentQueue<house.Rectangle> ();
        PointD p1, p2, p3, p4;
        p1 = new PointD (55, 250);
        p2 = new PointD (65, 250);
        p3 = new PointD (65, 90);
        p4 = new PointD (55, 90);
        rect = new house.Rectangle (p1, p2, p3, p4);
        WallHouseQ.Enqueue (rect);
        Parallel.For (0, 27, (i) => {
            p1.X += 10;
            p2.X += 10;
            p3.X += 10;
            p4.X += 10;
            rect = new house.Rectangle (p1, p2, p3, p4);
            Helper.wastetime (compLevel);
            WallHouseQ.Enqueue (rect);
            Gtk.Application.Invoke (delegate {
                if (drawArea == null)
                    return;
                Cairo.Context ct = Gdk.CairoHelper.Create (drawArea.GdkWindow);
                DrawHouse = new house.DrawHouse (ct, WallHouseQ);
                DrawHouse.DrawRectangles ("Wall");
                ((IDisposable)ct.Target).Dispose ();
                ((IDisposable)ct).Dispose ();
                }
            );
            }
        );
    }
4

1 回答 1

6

您的p1// p2/变量不是线程安全的p3p4因此您可能会在现有矩形的顶部进行绘制。

您可以根据当前索引计算适当的位置,而不是每次都增加。例如:

Parallel.For(0, 27, i =>
{
    // Make new points...
    PointD p1New = new PointD(55 + (i+1)*10, 250);
    //...

    // Make sure you don't share variables here, either - ie: make a new rect from the new points
    house.Rectangle rectNew = new house.Rectangle (p1New, p2New, p3New, p4New);
于 2012-09-18T17:58:27.120 回答