2012-10-29 2 views
1

저는 WPF와 C#을 사용하여 첫 프로그램을 작성하고 있습니다.WPF 컨트롤에 대한 스레드 안전 호출

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

이 잘 작동하고 Window.Loaded 이벤트에서 나는이 캔버스 PitchPanel 전화에 액세스 할 수 있습니다 내 창은 단순한 캔버스 컨트롤이 포함되어 있습니다. 당신이 볼 수 있듯이

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라는 스레드가 :

는 이제 다음과 같이 초기화 Game라는 클래스를 추가했습니다. 이 같은 가능한 최고 속도로 현재 게임 상태를 다시 그려야 :

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에 주어진 같은 원리라고 생각합니다.

그럼 왜 작동하지 않습니까? 아무도 다른 스레드에서 컨트롤에 대한 호출을 수행하는 방법을 알고 있습니까?

+0

[스레딩 모델 참조] (http://msdn.microsoft.com/en-us/library/ms741870.aspx)를 읽으십시오. 또한 [이 질문] (http://stackoverflow.com/questions/11923865/how-to-deal-with-cross-thread-access-exceptions)을 참조하십시오. –

답변

1

다른 스레드에서 WPF 개체를 만들 수 없으며 Dispatcher 스레드에도 만들어야합니다.

이 :

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

대리자로 이동해야합니다.

+0

그게 전부입니다. 이제는 효과가있는 것 같습니다. 정말 고맙습니다. –