2011-08-12 33 views
3

今天我遇到了一個非常有趣的問題,我很幸運能夠很快解決,但我想知道問題的本質。計時器神祕 - Forms.Timer與Threading.Timer

我寫了一個管理操縱桿操作的控件類。我想開始一些行動,並在按鈕點擊後啓動計時器,並在計時器間隔後停止此操作。

我有一個類(僞),看起來像這樣:

public class Joystick : UserControl 
{ 
    private Form.Timer timer; //or System.Threading.Timer 
    public void Init() 
    { 
     timer.Tick += new EventHandler(timerCallback) //Threading.Timer(timerCallback) 
     timer.Stop();//timer.Change(Timeout.Infinite, Timeout.Infinite); 
    } 

    public void ButtonCallback() 
    { 
     StartSomething(); 
     timer.Stop(); 
     timer.Start(); //timer.Change(500, Timeout.Infinite); 
    } 

    public void timerCallback() 
    { 
    StopSomething(); 
    timer.Stop();//timer.Change(Timeout.Infinite, Timeout.Infinite); 
    } 
} 

我有兩個應用,一個是非常簡單的(只是一種形式),第二個是比較複雜的,但是這背後的複雜性仍然是一個包含此UserControl的普通窗體(以及DotNetMagicForm)。管理代碼在兩個應用程序中都是完全相同的,但在更復雜的應用程序中,timerCallback()從未被調用過。簡單的一切都很好。 init在兩種情況下都被調用(斷點)。即使我在ButtonCallback中分配了timerCallback - timerCallback仍然沒有被調用。

我遵循我的同事的建議,並通過使用Threading.Timer而不是Forms.Timer重寫它,並突然它開始在這兩個應用程序中工作。我們都不知道爲什麼。

我知道我的問題很模糊,但是這個問題的根源是什麼?

感謝

回答

5

Threading.Timer不使用UI消息泵回調蜱。它使用ThreadPool線程來執行此操作。

UI定時器只是將消息發佈到表單的消息泵來請求回調。你的背景魔法表單根本就沒有收到這些消息。我不知道爲什麼,也許是因爲表單在另一個沒有消息泵的線程上,或者不活動的表單也許不會處理這個泵。

1

你吃過看看this文章比較不同.NET定時器類

0

Windows窗體計時器想送WM_TIMER到消息隊列。您的消息隊列可能太忙,無法處理其他窗口消息,或者消息可能沒有首先提交。你可能想用Spy ++這樣的工具來弄清楚會發生什麼(它應該作爲visual studio的一部分安裝)。