后台计时器只在一个线程中工作C#

时间:2010-10-14 13:14:41

标签: c# wpf multithreading c#-4.0 timer

我有一个尴尬的问题,我在.NET 4.0中使用C#和WPF,我需要的是一个只创建一个线程的计时器,但它需要在后台工作,所以不在主线程,问题是使用System.Windows.Forms.Timer或DispatchTimer将自动强制它在主线程上工作并受UI影响,另一方面使用System.Timers.Timer或System.Threading.Timer将创建对于超出时间间隔的每个周期的新线程,这将发生,因为经过的计时器事件中的代码有点大,尽管其中一部分被进一步发送给后台工作者。

所以我在想是否有可能强制说System.Timers.Timer在后台工作并且永远不会产生到多个线程,我也向其他建议开放

3 个答案:

答案 0 :(得分:1)

只需使用周期为0的System.Threading.Timer,以便回调只运行一次。一切都完成后,给计时器充电,以便以后再次点火。你只能保证一个线程以这种方式运行。

答案 1 :(得分:1)

使用System.Timers.Timer,它在ThreadPool线程上触发其已用事件处理程序。输入事件处理程序后,立即停止计时器。在事件处理程序结束时,启动计时器,它将从其间隔开始开始倒计时。

这是一个简单的例子,它有一个100ms的计时器,它在已经过去的事件处理程序中花了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();
}

答案 2 :(得分: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();