2010-03-23 112 views
1

在我正在開發的VSTO加載項中,我需要執行具有特定延遲的方法。棘手的部分是該方法可能需要0.1秒到1秒的時間才能執行。我目前使用System.Timers.Timer這樣的:C# - 重複使用計時器的方法調用

private Timer tmrRecalc = new Timer(); 

    // tmrRecalc.Interval = 500 milliseconds 

    private void tmrRecalc_Elapsed(object sender, System.Timers.ElapsedEventArgs e){ 

     // stop the timer, do the task 
        tmrRecalc.Stop();      
        Calc.recalcAll(); 
        
        // restart the timer to repeat after 500 ms 
        tmrRecalc.Start(); 
    } 

基本上開始其中,提出了在這之後停止執行任意長度的任務1對過去的事件。但UI線程似乎在每個任務之間掛起3-5秒。

定時器是否有'預熱'時間開始?這就是爲什麼它第一次(也是最後一次)耗時如此之久?

我使用哪種類型的計時器?

+0

'Calc.recalcAll()'函數是否與任何UI控件交互? – dan 2010-03-24 00:26:30

+0

是的,它確實需要。 – 2010-03-28 02:48:35

回答

2

而不是使用計時器,我建議在不同的線程(產生線程)中進行計算,並使用Thread.Sleep(毫秒)在間隔之間休眠。這對我來說非常有用。

+0

以前從未做過多線程。我如何產生一個線程,並可以很容易地與UI線程一起工作? (不要問我爲每個我想調用的方法編寫組件) – 2010-03-24 01:21:05

+0

是的,它可以很好地處理UI線程,如果要更新主線程的UI,只需在主線程上調用BeginInvoke即可。這只是兩條線。 .Net對線程有非常好的支持,基本上你只需要把方法的名字提供給一個新的線程對象(System.Threading.Thread)。在多進程計算的這些日子裏,你離不開線程。 實際上,我已經開始學習新的.Net 4中的並行任務庫,以便我可以在未來的軟件中充分利用多個處理器。 – 2010-03-24 04:13:47

2

也許你的計算時間比你想象的要長。定時器沒有任何熱身。

是否有任何理由不能使用後臺線程,也許一個BackgroundWorker對象來運行計算而不需要定時器?

+0

如果我使用功能區UI上的按鈕手動調用'Calc.recalcAll'方法,則完全按照前面所述,每次調用0.1秒到1秒完全執行。 BackgroundWorker可以使用UI線程嗎? – 2010-03-24 01:19:53

+0

說實話,我自己並沒有使用過BackgroundWorkers。但是你可以很容易地創建新的Thread對象,設置一個ThreadStart委託,然後啓動它們。當你的計算更新時,你可以讓他們觸發你的UI功能,但是你需要編組他們。很簡單 - 或者讓後臺函數調用UI上的任何控件的Invoke,或者使用InvokeRequired塊來保護您的控件。你可以在谷歌或SO上查看後一種模式。 – Tesserex 2010-03-24 01:45:42

+0

要清楚,它在技術上並不重要,你調用什麼控制調用。你的用戶界面上的任何東西都可以。重要的是,該對象是在具有運行消息循環的線程(由Application.Run創建的)創建的。 – Tesserex 2010-03-24 01:47:17