0

I have a problem with Multithreading.

I'm doing a project in which we have a train, rail crossing and a car. The train is moving, and the rail crossing and car stop if required. All three thing are on different threads. there are 2 buttons, one starts moving the train, the second creats a new PictureBox car.

To move train I used simply use for loop that by Invoke changes the location of the PictureBox. The rail crossing just checks the location of the train and changes the light to red when the train is in a specific location.

Creating the car looks like this :

private void Operation1()
{
    this.BeginInvoke((MethodInvoker)delegate()
    {
        PictureBox a = new PictureBox();
        a.Location = new Point(333, 361);
        a.BackColor = Color.Black;
        a.Size = new Size(20, 37);
        Controls.Add(a);
    });
}

The car is created and it's fine. Now I would like to move a car in Operation1() with loop like this:

private void Operation1()
    {
        this.BeginInvoke((MethodInvoker)delegate()
        {
            PictureBox a = new PictureBox();
            a.Location = new Point(333, 361);
            a.BackColor = Color.Black;
            a.Size = new Size(20, 37);
            Controls.Add(a);
            for (int i = 0; i < 140; i++)
            {
                a.Location = new Point(a.Location.X, a.Location.Y - 3);
                Thread.Sleep(50);
            }
        });
    }

But when it starts the car disappears, if the other thread was running it stops and waits until this loop ends. Where is the problem? I hope someone can help me as fast as possible.

Timothy Groote
  • 8,614
  • 26
  • 52
addictive
  • 48
  • 3
  • 1
    There is nothing causing the form to redraw, take a look at http://stackoverflow.com/questions/2376998/force-form-to-redraw – tolanj Oct 27 '14 at 14:25
  • Ok, problem with disappearing car is gone. but weird i dont use it at Train and its working :). Thank you anyway. But still have no idea why other threads stops when for is looping – addictive Oct 27 '14 at 14:50

2 Answers2

0

You need to force the controls to redraw. Take a look at the Control.Refresh() method for Windows Forms. For WPF you may take a look into this thread.

Christian St.
  • 1,751
  • 2
  • 22
  • 41
0

Instead of using this.BeginInvoke, try to create another Thread to update the UI. Encapsulate your objects in one class and read the position from that class.

When you use Invoke like this to update the UI, the thread is handed over to the UI thread and it freezes everything all the time, it's totally crap. :)

Hangarter
  • 582
  • 4
  • 12
  • if there is option can you explain how it should work? I'm pretty new at multithreading – addictive Oct 28 '14 at 20:24
  • Usually what I have done was to create a background worker (if it's a desktop project) or a thread if it's something else. Basically you have you main thread (the one the controls the UI) and you fire a Thread that has a method responsable for reading information from other classes then updating the UI objects. The background worker has an event that fires when its work is done: there you insert your code to update the UI based on somewhere else information. – Hangarter Oct 31 '14 at 10:05
  • The event BackgroundWorker.OnRunWorkerCompleted (http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.onrunworkercompleted(v=vs.110).aspx) is particularly useful. – Hangarter Oct 31 '14 at 14:28