user207809
user207809

Reputation: 61

drawing an ellipse in wpf from within a secondary thread

I am writing a wpf application in which balls are bouncing independently on a canvas, each ball in a different thread. Each time the user clicks on the canvas a new thread is added to the threadpool and an ellipse representing the ball is created. In order to add the ellipse and draw it I use Dispatcher.Invoke. However, the command myCanvas.Children.Add(el); called from within the code surrounded by Invoke causes the application to crash the moment the Invoke block ends, by entering break mode. Obviously, this is not the way to achieve my goal, so how can I do it?

        Dispatcher.Invoke(new Action(() =>
        {
            Ellipse el = new Ellipse();
            el.Fill = color1;
            el.Margin = new Thickness(10);
            el.Height = 40;
            el.Width = 40;
            balls.Add(ballsCounter, el);
            Canvas.SetTop(el, p.Y - 2 * el.Height / 3);
            Canvas.SetLeft(el, p.X - 2 * el.Width / 3);
            myCanvas.Children.Add(el);
            tbNumBalls.Text = ballsCounter.ToString();
        }));

Upvotes: 0

Views: 403

Answers (1)

mm8
mm8

Reputation: 169190

You can't create the Ellipse on one (UI) thread and then add it to a Canvas that was created on another (UI) thread.

This is not possible because of fact that WPF uses a single threaded exeuction model with thread affinity. This basically means that a UI control cannot be accessed from any other thread than the one on which it was originally created. There are checks in the base classes that enforce this by throwing InvalidOperationExceptions whenever you try to do this.

So you should either create all controls on the same thread, or keep them forever separated on different threads.

Upvotes: 1

Related Questions