2010-06-22 9 views
8

Quindi sto creando un semplice rompicapo in C#/wpf. Mi sto imbattendo in un problema che utilizza i timer, mi sembra che sia probabilmente una soluzione semplice, ma qui sta accadendo. Ogni volta che t_Elapsed viene attivato tenta di chiamare Update() ma quando fa il suo OMG Im non è nel thread corretto, quindi non posso farlo signore. Come invoco il metodo dal gioco dalla discussione corretta? (E sì, lo so il codice è brutto e ha numeri magici, ma ho solo un pò chugged fuori senza mettere un sacco di fatica in. E sì che avere zero giochi programmazione esperienza)Il thread chiamante non può accedere a questo oggetto perché ne possiede uno diverso.

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 Im non nel thread giusto così non posso fare che sir.' <3 – Laserbeak43

risposta

11

si consiglia di utilizzare l'oggetto DispatcherTimer invece, assicurerà che gli eventi del timer vengano pubblicati nella discussione corretta.

+0

è leggermente API diverse. Come ElapsedTimeEvent ora è denominato TickEvent. Ma dopo la migrazione alla nuova API funziona perfettamente con il thread dell'interfaccia utente! Adoro .NET per avere una soluzione rapida per quasi ogni occasione;) – OneWorld

5

Gli eventi scaduti dal timer si attivano su un thread dal pool di thread (http://www.albahari.com/threading/part3.aspx#_Timers) e non sul thread dell'interfaccia utente. Il tuo approccio migliore è quello di richiamare dispatcher del controllo attraverso una chiamata del genere:

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

     return null; 
    }), null); 
+1

+1 DispatcherTimer non ha funzionato, questo è quello che ha fatto per me –

Problemi correlati