Thread-safe calls to WPF controls

我与影子孤独终老i 提交于 2019-12-13 00:53:32

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!