我只是寫我的第一個程序使用WPF和C#。我的窗戶只是包含了一個簡單的畫布控制:線程安全調用WPF控件
<StackPanel Height="311" HorizontalAlignment="Left" Name="PitchPanel" VerticalAlignment="Top" Width="503" Background="Black" x:FieldModifier="public"></StackPanel>
能正常工作,並從Window.Loaded
事件中,我可以訪問此帆布稱爲PitchPanel
。
現在我已經加入了一個名爲Game
類,這是這樣的初始化:
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();
//...
}
正如你可以看到,有一個叫GraphicsThread
線程。這項工作應在可能的最高速度這樣重繪當前的遊戲狀態:
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);
}));
}
}
但是,儘管我用這是由它在創建遊戲實例傳遞主窗口中,未處理的異常調用的調度發生:[System.Reflection.TargetInvocationException]
,內部異常說我不能訪問該對象,因爲它由另一個線程(主線程)擁有。
遊戲初始化應用程序的Window_Loaded事件:
GameInstance = new TeamBall.Game(this, PitchPanel);
我覺得這是在this answer給出了相同的原則。
那麼,爲什麼這不起作用?有人知道如何從另一個線程調用控件嗎?
閱讀[線程模型參考](http://msdn.microsoft.com/en-us/library/ms741870.aspx)?另見[這個問題](http://stackoverflow.com/questions/11923865/how-to-deal-with-cross-thread-access-exceptions)。 –