2010-10-14 89 views
0

我有一個有點尷尬的問題,我正在與C#和WPF在.NET 4.0中,我需要的是一個計時器,將只創建一個線程,但它將需要工作背景,所以不在主線程中,問題是使用System.Windows.Forms.Timer或DispatchTimer會自動強制它在主線程上工作並受到UI的影響,另一方面使用System.Timers.Timer或者System.Threading.Timer會爲超過時間間隔的每個週期創建一個新的線程,因爲經過的定時器事件中的代碼有點大,儘管它的一部分被進一步發送給後臺工作者,但這會發生。背景計時器只能工作在一個線程C#

,所以我想如果有可能迫使,說System.Timers.Timer,在後臺工作,從來沒有釀出更然後一個線程,也是我打開其他建議

+1

你要什麼發生,如果出現下一個節拍,而當前週期仍在處理? – Justin 2010-10-14 13:31:56

+0

你想用後臺線程完成什麼?它只是需要運行的東西,計時器需要確保線程存在? – 2010-10-14 13:37:09

+0

@justin:我想等待當前的循環完成處理 – WarBorg 2010-10-19 10:49:55

回答

1

使用System.Timers.Timer,它會在ThreadPool線程上觸發其已過去的事件處理程序。只要你進入事件處理程序,停止計時器。在事件處理程序結束時,啓動計時器,它將從其間隔的開始處開始倒計時。

這裏有一個簡單的例子,一個100毫秒計時器,花2秒在它經過的事件處理程序:

static void Main(string[] args) 
{ 
    System.Timers.Timer myTimer = new System.Timers.Timer(100); 
    myTimer.Elapsed += new System.Timers.ElapsedEventHandler(myTimer_Elapsed); 
    myTimer.Start(); 
    Console.ReadLine(); 
} 

static void myTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) 
{ 
    ((System.Timers.Timer)sender).Stop(); 
    Console.WriteLine(DateTime.Now.ToString("HH.mm.ss")); 
    System.Threading.Thread.Sleep(2000); 
    ((System.Timers.Timer)sender).Start(); 
} 
+0

是的,謝謝,這似乎是得到我需要的最簡單的方法 – WarBorg 2010-10-19 10:53:10

+0

System.Threading.Timer也在ThreadPool線程中執行,並且不必在每個Elapsed事件上重新初始化它。 – 2012-02-07 03:49:21

1

只需使用一個System.Threading.Timer的週期爲0,以便回調只運行一次。當一切完成後,給計時器充電,以便稍後再次啓動。你將只能保證以這種方式運行一個線程。

1

DispatcherTimer有一個構造函數重載,可以讓你做你想要什麼。 用它在你的線程的上下文:

using System.Threading; 
using WpfThreading = System.Windows.Threading; 

... 

Thread t = new Thread(() => 
{ 
    var interval = TimeSpan.FromSeconds(3.0); 
    var priority = WpfThreading.DispatcherPriority.Background; 
    EventHandler callback = (a, e) => { }; 
    var dispatcher = WpfThreading.Dispatcher.CurrentDispatcher; // dispatcher for this thread 
    WpfThreading.DispatcherTimer dt = new WpfThreading.DispatcherTimer(interval, priority, callback, dispatcher); 

    bool sameDispatchers = WpfThreading.Dispatcher.CurrentDispatcher == this.Dispatcher; // false 
}); 
t.Start();