1

I am just writing my first program using WPF and C#. My windows just contains a simple canvas control:

<StackPanel Height="311" HorizontalAlignment="Left" Name="PitchPanel" VerticalAlignment="Top" Width="503" Background="Black" x:FieldModifier="public"></StackPanel>

This works fine and from the Window.Loaded event I can access this Canvas called PitchPanel.

Now I have added a class called Game which is initialized like this:

public Game(System.Windows.Window Window, System.Windows.Controls.Canvas Canvas)
{
    this.Window = Window;
    this.Canvas = Canvas;
    this.GraphicsThread = new System.Threading.Thread(Draw);
    this.GraphicsThread.SetApartmentState(System.Threading.ApartmentState.STA);
    this.GraphicsThread.Priority = System.Threading.ThreadPriority.Highest;
    this.GraphicsThread.Start();
    //...
}

As you can see, there is a thread called GraphicsThread. This should redraw the current game state at the highest possible rate like this:

private void Draw() //and calculate
{
   //... (Calculation of player positions occurs here)
   for (int i = 0; i < Players.Count; i++)
   {
       System.Windows.Shapes.Ellipse PlayerEllipse = new System.Windows.Shapes.Ellipse();
       //... (Modifying the ellipse)
       Window.Dispatcher.Invoke(new Action(
       delegate()
       {
           this.Canvas.Children.Add(PlayerEllipse);
       }));
    }
}

But although I have used a dispatcher which is invoked by the main window which is passed at the creation of the game instance, an unhandled exception occurs: [System.Reflection.TargetInvocationException], the inner exceptions says that I cannot access the object as it is owned by another thread (the main thread).

The Game is initialized in the Window_Loaded-event of the application:

GameInstance = new TeamBall.Game(this, PitchPanel);

I think this is the same principle as given in this answer.

So why does this not work? Does anybody know how to make calls to a control from another thread?

Community
  • 1
  • 1
1' OR 1 --
  • 1,694
  • 1
  • 16
  • 32
  • Read the [threading model reference](http://msdn.microsoft.com/en-us/library/ms741870.aspx)? Also see [this question](http://stackoverflow.com/questions/11923865/how-to-deal-with-cross-thread-access-exceptions). – H.B. Oct 29 '12 at 20:01

1 Answers1

1

You cannot create a WPF object on a different thread - it must also be created on the Dispatcher thread.

This:

System.Windows.Shapes.Ellipse PlayerEllipse = new System.Windows.Shapes.Ellipse();

must go into the delegate.

flq
  • 22,247
  • 8
  • 55
  • 77