2010-06-22 6 views
8

Donc je fais un simple jeu de briques en C#/wpf. Je me heurte à un problème en utilisant des minuteurs, je pense que c'est probablement une solution simple, mais voici ce qui se passe. Chaque fois que t_Elapsed est déclenché, il tente d'appeler Update() mais quand il fait comme son OMG Im n'est pas dans le bon fil donc je ne peux pas faire ce monsieur. Comment puis-je invoquer la méthode du jeu à partir du fil approprié? (Et oui, je sais que le code est laid et a des nombres magiques mais je juste un peu ingurgité ce sans mettre beaucoup d'efforts. Et oui j'avoir des jeux de programmation expérience zéro)Le thread appelant ne peut pas accéder à cet objet car un thread différent le possède

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 je ne suis pas dans le fil droit, donc je ne peux pas faire que sir.' <3 – Laserbeak43

Répondre

11

Vous devez utiliser l'objet DispatcherTimer à la place, il s'assurera que les événements de minuterie sont publiés dans le bon thread.

+0

a un peu API différente. Comme ElapsedTimeEvent est maintenant nommé TickEvent. Mais après la migration vers une nouvelle API, cela fonctionne très bien avec le thread de l'interface utilisateur! J'adore .NET pour avoir une solution rapide pour presque toutes les occasions;) – OneWorld

5

Les événements de temporisation écoulés se déclenchent sur un thread du pool de threads (http://www.albahari.com/threading/part3.aspx#_Timers) et non sur le thread d'interface utilisateur. Votre meilleure approche est d'invoquer le répartiteur par un appel du contrôle comme celui-ci:

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

     return null; 
    }), null); 
+1

+ 1 DispatcherTimer n'a pas fonctionné, c'est ce que j'ai fait pour moi –

Questions connexes