-3

I am trying to make two threads work at the same time on the same panel in a windows form, the threads are the same. I have looked for answers already but no question treated this thing (at least from what i saw). here is the code :

The code in the form.cs :

semaphore = new Semaphore();



    p1t1 = new PanelThread(new Point(10, 10),
                         150, Direction.West, Track.track1, pnl1, typetrain.loco,
                         Color.Blue,
                         semaphore
                         );



    p2t2 = new PanelThread(new Point(390, 390),
                         150, Direction.East, Track.track2, panel5, typetrain.loco,
                         Color.Red,
                         semaphore
                         );

    green1t1 = new PanelThread(new Point(10, 10),
                         150, Direction.North, Track.track1, pnl1, typetrain.wagon,
                         Color.Green,
                         semaphore
                         );


    semThread = new Thread(new ThreadStart(semaphore.Start));

    thread1 = new Thread(new ThreadStart(p1t1.Start));

    thread2 = new Thread(new ThreadStart(p2t2.Start));

    thread3 = new Thread(new ThreadStart(green1t1.Start));

    this.Closing += new CancelEventHandler(this.Form1_Closing);

    semThread.Start();
    thread1.Start();
    thread2.Start();
    thread3.Start();

the code in the panelthread.cs :

public PanelThread(Point origin,
                       int delay,
                       Direction direction,
                       Track track,
                       Panel panel,
                       typetrain locwag,
                       Color colour,
                       Semaphore semaphore)
    {
        this.origin = origin;
        this.delay = delay;
        this.direction = direction;
        this.panel = panel;
        this.colour = colour;
        this.plane = origin;
        this.panel.Paint += new PaintEventHandler(this.panel_Paint);
        this.track = track;
        this.locwag = locwag;
        switch (this.direction)
        {
            case Direction.East:
                this.xDelta = -10;
                this.yDelta = 0;
                break;

            case Direction.West:
                this.xDelta = +10;
                this.yDelta = 0;
                break;

            case Direction.North:
                this.xDelta = 0;
                this.yDelta = -10;
                break;

            case Direction.South:
                this.xDelta = 0;
                this.yDelta = +10;
                break;
        }


        this.semaphore = semaphore;
    }

When I launch the program, the program bugs at the paint event handler with an System.ArgumentException at the line g.FillRectangle:

private void panel_Paint(object sender, PaintEventArgs e)
{
    Graphics g = e.Graphics;

    SolidBrush brush = new SolidBrush(colour);
    g.FillRectangle(brush, plane.X, plane.Y, 10, 10);

    brush.Dispose();    //  Dispose of graphic
    g.Dispose();        //  resources  
}

UPDATE : I have tried using invoke in the panelthread.cs like this :

if (this.panel.InvokeRequired)
    {
        this.panel.Invoke((MethodInvoker)delegate { this.panel.Paint += new PaintEventHandler(this.panel_Paint); });
    }

I don't have any error now, but the squares are not being created, so i don't go at all in the panel_paint function. I surely have written something wrong in the Invoke calling, or I wrote it in the wrong place.

raiskader
  • 89
  • 4
  • 16
  • 4
    Please don't post code as screen shots, but paste the relevant code as text in your question. This makes it easier for us to reproduce a problem, and to use it in answers and for others to search. To your problem: you should not access UI elements from different threads. Access to UI elements should be synchronized on the UI thread that created the UI element. Look for `Control.Invoke` or `Control.BeginInvoke` to invoke an action on the UI thread. – René Vogt Mar 30 '17 at 13:44
  • Maybe this helps you: https://stackoverflow.com/questions/142003/cross-thread-operation-not-valid-control-accessed-from-a-thread-other-than-the?rq=1 – René Vogt Mar 30 '17 at 13:46
  • thanks for the answer, I used screens because I thought the code would be too big, I will keep it in mind for the future – raiskader Mar 30 '17 at 13:47
  • I just updated the thread to show the code directly – raiskader Mar 30 '17 at 13:58
  • I tried using invoke, but the code gets blocked, I added more detail in the question – raiskader Mar 30 '17 at 15:00
  • The paint event (and actual painting) will always have to be in the UI thread. There's no reason to try to put that into a thread as it will always just require a invoke back to the main thread every time it is called. – David Mar 30 '17 at 16:17

1 Answers1

0

I actually found the error, and having found that the panel_paint is actually always on the main thread, the error was somewhere else. In the end, I saw that I only needed to take out the g.dispose command in panel_paint, as it destroyed the graphic before painted the next object.

raiskader
  • 89
  • 4
  • 16
  • Thank you for coming back with a solution to your own problem! Now that you've solved it, you can also choose to delete your question if you think there's no use in keeping it around. – PJvG Apr 03 '17 at 08:58