2010-06-22 55 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我不是在正確的線程,所以我不能做到這一點sir.' <3 – Laserbeak43 2012-10-21 10:10:38

回答

11

您應該使用DispatcherTimer對象相反,它會確保定時器事件發佈到正確的線程。

+0

略有不同的API。像ElapsedTimeEvent現在名爲TickEvent。但是在遷移到新的API之後,它在UI線程中效果很好!我喜歡.NET因爲幾乎每一個場合都有一個快速解決方案;) – OneWorld 2013-01-28 13:56:20

5

定時器已用事件從線程池(http://www.albahari.com/threading/part3.aspx#_Timers)在線程上觸發,而不是在UI線程上觸發。你最好的方法是通過這樣的調用來調用控件的調度員:

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

     return null; 
    }), null); 
+1

+1 DispatcherTimer沒有工作,這是對我的工作 – 2014-06-24 01:07:32

相關問題