gpt4 book ai didi

c# - 计时器在跨线程中不起作用

转载 作者:太空狗 更新时间:2023-10-29 22:26:52 26 4
gpt4 key购买 nike

我的 form 中有 2 个全局 System.Windows.Forms.Timer。两者都在表单的构造函数中初始化。但还没有开始。构造函数启动一个新线程,该线程启用并启动两个计时器。明明都是跨线程,但是并没有抛出任何跨线程异常。但它甚至不起作用。它不会触发 Timer.Tick 方法。这是代码:

第一种方法:

在表单构造函数中:

    KeepMeAliveTimer = new Timer();  //timer 1
KeepMeAliveTimer.Interval = 15000;
KeepMeAliveTimer.Tick += KeepMeAlive;
timer1 = new Timer(); //timer 2
timer1.Interval = 15000;
timer1.Tick += timer1_Tick;
//started a new thread

换句话说:

    //after performing some tasks, it enables the timers
KeepMeAliveTimer.Enabled = true; //timer 1
KeepMeAliveTimer.Start();
timer1.Enabled = true; //timer 2
timer1.Start();

但它没有触发 Timer 的滴答事件,甚至没有抛出任何异常。

第二种方法:

但是当我在同一线程(主线程)中初始化并启用 Timers 时,它们运行良好:

    KeepMeAliveTimer = new Timer();   //timer 1
KeepMeAliveTimer.Interval = 15000;
KeepMeAliveTimer.Tick += KeepMeAlive;
KeepMeAliveTimer.Enabled = true;
KeepMeAliveTimer.Start();
timer1 = new Timer(); //timer 2
timer1.Interval = 15000;
timer1.Tick += timer1_Tick;
timer1.Enabled = true;
timer1.Start();

现在的问题是;如果连任何异常都没有,为什么第一种方法不起作用?

最佳答案

Timer 类是线程安全的,但不是您期望的那样。在工作线程上调用 Start() 方法实际上会启动计时器。该类完成了创建隐藏窗口的工作,因此它可以调用 SetTimer winapi 函数并在完成时接收 WM_TIMER 消息。

但是如果没有人在监听该消息,则不会引发 Tick 事件。您肯定不会,您肯定没有在该线程上调用 Application.Run() 。因此,您不应在工作线程上启动计时器。如有必要,请使用 Control.BeginInvoke 在 UI 线程上启动它。

或者使用 System.Threading.Timer 或 System.Timers.Timer,它们不依赖于消息循环。您必须正确地互锁,它们的 Elapsed 事件或回调在 另一个 线程上运行。哪种解决方案往往会产生另一个问题。

关于c# - 计时器在跨线程中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17244469/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com