从另一个类取消线程计时器
本文关键字:线程 计时器 取消 另一个 | 更新日期: 2023-09-27 18:32:27
我正在尝试在自己的代码中实现Thread.Timers的MSDN示例(http://msdn.microsoft.com/en-us/library/swx5easy.aspx)。
我希望能够在执行某个用户操作时取消计时器,但是我无法处理计时器,我怀疑这是因为我正在从另一个类调用方法,所以我需要调整; 但我不知道在哪里。
除此之外,计时器工作正常。谁能看到为什么我的计时器在调用 btnconfigOpenConfig 时不会取消?
仅供参考,我正在将工作进程转换为定时事件。
public partial class Xservt : Window
{
internal class TimerStateObjClass
{
public int SomeValue;
public System.Threading.Timer SqlUpdateFromTwitterTimerReference;
public bool TimerCanceled;
}
internal void SomeMethod(){
TimerStateObjClass stateObj = new TimerStateObjClass();
stateObj.TimerCanceled = false;
stateObj.SomeValue = 100;
System.Threading.TimerCallback timerDelegate =
new System.Threading.TimerCallback(twit.hometimelineclass._sqlUpdateFromTwitterWorker_DoWork);
var sqlUpdateFromTwitterTimer = new Timer(timerDelegate, stateObj, 0,20000);
stateObj.SqlUpdateFromTwitterTimerReference = sqlUpdateFromTwitterTimer;
}
}
//action to perform which disposes the timer
private void btnconfigOpenConfig(object sender, RoutedEventArgs e)
{
TimerStateObjClass timerState = new TimerStateObjClass();
timerState.TimerCanceled = true;
}
//Actions the timer is calling, in another class
internal static void _sqlUpdateFromTwitterWorker_DoWork(object StateObj)
{
Xservt.TimerStateObjClass state = (Xservt.TimerStateObjClass) StateObj;
if(state.TimerCanceled)
{
state.SqlUpdateFromTwitterTimerReference.Dispose();
}
//some work
}
正如 Hans 在注释中指出的那样,您需要保留对最初创建的 TimerStateObjClass 的引用。 然后,您可以使用它来设置计时器已取消。
public partial class Xservt : Window
{
internal class TimerStateObjClass
{
public int SomeValue;
public System.Threading.Timer SqlUpdateFromTwitterTimerReference;
public bool TimerCanceled;
}
TimerStateObjClass stateObj; //THIS IS THE ORIGINAL STATE OBJ
internal void SomeMethod()
{
stateObj = new TimerStateObjClass();
stateObj.TimerCanceled = false;
stateObj.SomeValue = 100;
System.Threading.TimerCallback timerDelegate = new System.Threading.TimerCallback(twit.hometimelineclass._sqlUpdateFromTwitterWorker_DoWork);
var sqlUpdateFromTwitterTimer = new Timer(timerDelegate, stateObj, 0, 20000);
stateObj.SqlUpdateFromTwitterTimerReference = sqlUpdateFromTwitterTimer;
}
//action to perform which disposes the timer
private void btnconfigOpenConfig(object sender, RoutedEventArgs e)
{
//HERE WE CAN GET AT THE ORIGINAL STATE OBJ
stateObj.TimerCanceled = true;
}
}
//Actions the timer is calling, in another class
internal static void _sqlUpdateFromTwitterWorker_DoWork(object StateObj)
{
Xservt.TimerStateObjClass state = (Xservt.TimerStateObjClass)StateObj;
if (state.TimerCanceled)
{
state.SqlUpdateFromTwitterTimerReference.Dispose();
}
//some work
}
- 您需要将对计时器(或引用计时器的类)的引用存储在类中的某个位置。
- 要停止计时器,无需处理它。你可以打电话给
timer.Change(-1, -1);
.这将允许通过调用timer.Change(dueTimeInMs, intervalInMs);
再次重新启用计时器
你的代码应该是这样的:
public partial class Xservt : Window
{
private Timer timer = new Timer(o => DoSomething());
private void StartTimer()
{
var period = 5 * 1000; // 5 sec
timer.Change(0, period);
}
private void StopTimer()
{
timer.Change(-1, -1);
}
}
然后分别调用StartTimer
运行它,StopTimer
停止。
另请注意,如果DoSomething
的运行时间可能超过计时器间隔,则会导致在多个线程中同时运行该方法。为避免这种情况,请勿使用计时器的间隔,而应使用dueTime
:
private Timer timer = new Timer(o => {
DoSomething();
StartTimer();
});
private void StartTimer()
{
var period = 5 * 1000; // 5 sec
timer.Change(period, 0);
}
在此计时器中,被尝试仅运行一次,但在每次运行后都会重新触发。