C# 后台计时器仅在一个线程C中工作#
我有一个棘手的问题,我正在使用.NET 4.0中的C#和WPF,我需要的是一个计时器,它只会创建一个线程,但它需要在后台工作,所以不需要在主线程中工作,问题在于使用System.Windows.Forms.Timer或DispatchTimer将自动强制其在主线程上工作并受UI的影响,而在另一端,使用System.Timer.Timer或System.Threading.Timer将为超出时间间隔的每个周期创建一个新线程,这将发生,因为“已用计时器”事件中的代码有点大,尽管部分代码会进一步发送到后台工作程序C# 后台计时器仅在一个线程C中工作#,c#,wpf,multithreading,c#-4.0,timer,C#,Wpf,Multithreading,C# 4.0,Timer,我有一个棘手的问题,我正在使用.NET 4.0中的C#和WPF,我需要的是一个计时器,它只会创建一个线程,但它需要在后台工作,所以不需要在主线程中工作,问题在于使用System.Windows.Forms.Timer或DispatchTimer将自动强制其在主线程上工作并受UI的影响,而在另一端,使用System.Timer.Timer或System.Threading.Timer将为超出时间间隔的每个周期创建一个新线程,这将发生,因为“已用计时器”事件中的代码有点大,尽管部分代码会进一步发送到
因此,我在想,如果可以强制(比如System.Timers.Timer)在后台工作,并且不会产生超过一个线程,那么我也愿意接受其他建议,只需使用周期为0的System.Threading.Timer,以便回调只运行一次。当一切都完成后,给计时器充电,以便它稍后再次启动。您将保证只有一个线程以这种方式运行。只需使用周期为0的System.Threading.Timer,以便回调只运行一次。当一切都完成后,给计时器充电,以便它稍后再次启动。您将保证只有一个线程以这种方式运行。使用System.Timers.Timer,它将在线程池线程上触发其已用事件处理程序。进入事件处理程序后,立即停止计时器。在事件处理程序结束时,启动计时器,计时器将从其间隔开始倒计时 下面是一个简单的示例,其中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();
}
使用System.Timers.Timer,它在线程池线程上触发其已用事件处理程序。进入事件处理程序后,立即停止计时器。在事件处理程序结束时,启动计时器,计时器将从其间隔开始倒计时 下面是一个简单的示例,其中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();
}
Dispatchermer有一个构造函数重载,可以让您完全按照自己的意愿进行操作。 在线程的上下文中使用它:
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();
Dispatchermer有一个构造函数重载,可以让您完全按照自己的意愿进行操作。 在线程的上下文中使用它:
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();
如果在当前周期仍在处理的情况下发生下一个勾号,您希望发生什么?您试图用后台线程实现什么?这只是需要运行的东西吗,计时器需要确保线程存在吗?@justin:我想在当前周期结束时等待processing@paul:基本上,它需要运行和算法,我不想被GUI打断,GUI有一些中等GFX类型的语音,如果在当前周期仍在运行时出现下一个滴答声,您希望发生什么处理?你想用后台线程完成什么?这只是需要运行的东西,计时器需要确保线程存在吗?@justin:我想在当前周期结束时等待processing@paul:基本上它需要运行和算法,我不想被GUI打断,它有一些中等GFX类型的语音是的,谢谢,这似乎是获取所需内容的最简单方法System.Threading.Timer也会在线程池线程中执行,这样做的好处是不必在每次发生事件时重新初始化它。是的,谢谢,这似乎是获取所需内容的最简单方法System.Threading.Timer也会在线程池线程中执行,这样做的好处是不必在每次发生事件时重新初始化它。