2010-06-22 2 views
8

Так что я делаю простую игру с разбивкой кирпича в C#/wpf. Я сталкиваюсь с проблемой с использованием таймеров, я чувствую, что это, вероятно, простое решение, но вот что происходит. Всякий раз, когда t_Elapsed уволен, он пытается вызвать Update(), но когда он делает это, как OMG Im, не в нужном потоке, поэтому я не могу сделать это сэр. Как мне вызвать метод из игры из соответствующей нити? (И да, я знаю, что код уродлив и имеет магические числа, но я просто любопытный пыхтя его, не подвергая много усилий. И да, у меня есть ноль игры опыт программирования)Вызывающий поток не может получить доступ к этому объекту, потому что ему принадлежит другой поток.

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 не в правильном потоке, так что я не могу сделать это sir.' <3 – Laserbeak43

ответ

11

Вы должны использовать DispatcherTimer объект вместо этого он гарантирует, что события таймера будут опубликованы в правильном потоке.

+0

слегка различные API. Как ElapsedTimeEvent теперь называется TickEvent. Но после перехода на новый API он отлично работает с потоком пользовательского интерфейса! Я люблю .NET для быстрого решения почти для каждого случая;) – OneWorld

5

Таймер истек событий в потоке из потока пула (http://www.albahari.com/threading/part3.aspx#_Timers), а не в потоке пользовательского интерфейса. Ваш лучший подход для вызова диспетчера элемента управления через вызов, как это:

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

     return null; 
    }), null); 
+1

+1 DispatcherTimer не работал, вот что мне это дало –

Смежные вопросы

 Смежные вопросы