2012-04-28 78 views
0

取消線程Timer我試圖實現在自己的代碼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 
    } 
+3

您正在創建TimerStateObjClass的*新*的對象。這不能工作,而是向你的班級添加一個私人領域。 – 2012-04-28 13:17:01

+0

到TimerStateObjClass?類型TimerStateObjClass的 – Damo 2012-04-28 13:23:13

+0

,是。 – 2012-04-28 13:32:38

回答

0

正如漢斯在評論中指出的,你需要保持你最初創建TimerStateObjClass參考。然後您可以使用它來設置TimerCanceled。

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 
    } 
0
  1. 你需要參考保存到你的計時器(或類引用定時器)在類的地方。
  2. 要停止計時有沒有需要處理它。你可以撥打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); 
    } 

在此計時器trigrered只運行一次,但每次運行後,它被重新觸發。