我有一个尴尬的问题,我在.NET 4.0中使用C#和WPF,我需要的是一个只创建一个线程的计时器,但它需要在后台工作,所以不在主线程,问题是使用System.Windows.Forms.Timer或DispatchTimer将自动强制它在主线程上工作并受UI影响,另一方面使用System.Timers.Timer或System.Threading.Timer将创建对于超出时间间隔的每个周期的新线程,这将发生,因为经过的计时器事件中的代码有点大,尽管其中一部分被进一步发送给后台工作者。
所以我在想是否有可能强制说System.Timers.Timer在后台工作并且永远不会产生到多个线程,我也向其他建议开放
答案 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();