问题
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?
回答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.
来源:https://stackoverflow.com/questions/13128550/thread-safe-calls-to-wpf-controls