2010-06-22 6 views
8

Also mache ich ein einfaches Ziegelsteinbruchspiel in C#/wpf. Ich stoße auf ein Problem mit Timern, ich glaube, es ist wahrscheinlich eine einfache Lösung, aber hier ist was passiert. Immer wenn t_Elapsed abgefeuert wird, versucht es Update() aufzurufen, aber wenn es wie OMG funktioniert, bin ich nicht im richtigen Thread, also kann ich das nicht tun. Wie rufe ich die Methode vom Spiel aus dem richtigen Thread auf? (Und ja, ich weiß, dass der Code ist hässlich und magische Zahlen hat, aber ich tuckerte es nur irgendwie, ohne in viel Mühe zu setzen. Und ja, ich habe null Erfahrung Programmierung Spiele)Der aufrufende Thread kann nicht auf dieses Objekt zugreifen, weil ein anderer Thread es besitzt

public partial class Game : Grid 
{ 
    public bool running; 
    public Paddle p; 
    public Ball b; 
    Timer t; 

    public Game() 
    { 
     Width = 500; 
     Height = 400; 
     t = new Timer(20); 
     p = new Paddle(); 
     b = new Ball(); 
     for (int i = 15; i < 300; i += 15) 
     { 
      for (int j = 15; j < 455; j += 30) 
      { 
       Brick br = new Brick(); 
       br.Margin = new Thickness(j, i, j + 30, i + 15); 
       Children.Add(br); 
      } 
     } 
     Children.Add(p); 
     Children.Add(b); 
     p.Focus(); 
     t.AutoReset = true; 
     t.Start(); 
     t.Elapsed += new ElapsedEventHandler(t_Elapsed); 
    } 

    void t_Elapsed(object sender, ElapsedEventArgs e) 
    { 
     if (running) 
     { 
      Update(); 
     } 
    } 

    void Update() 
    { 
     b.Update(); //Error here when Update is called from t_Elapsed event 
    } 

    void Begin() 
    { 
     running = true; 
     b.Initiate(); 
    } 
} 
+0

'OMG Ich bin nicht in der richtigen Thread so kann ich nicht, dass sir.' tun <3 – Laserbeak43

Antwort

11

Sie sollten verwenden, um die DispatcherTimer Objekt Stattdessen wird sichergestellt, dass die Timer-Ereignisse im richtigen Thread veröffentlicht werden.

+0

Hat etwas verschiedene API. Wie ElapsedTimeEvent jetzt TickEvent heißt. Aber nach der Migration auf die neue API funktioniert es großartig mit dem UI-Thread! Ich liebe .NET für eine schnelle Lösung für fast jede Gelegenheit;) – OneWorld

5

Timer abgelaufene Ereignisse feuern auf einen Thread aus dem Thread-Pool (http://www.albahari.com/threading/part3.aspx#_Timers) und nicht auf dem UI-Thread. Ihre beste Ansatz ist die Kontrolle des Dispatcher durch einen Aufruf wie folgt aufzurufen:

yourControl.Dispatcher.BeginInvoke(
    System.Windows.Threading.DispatcherPriority.Normal 
    , new System.Windows.Threading.DispatcherOperationCallback(delegate 
    { 
     // update your control here 

     return null; 
    }), null); 
+1

+1 DispatcherTimer hat nicht funktioniert, das ist, was es für mich getan hat –

Verwandte Themen