2012-04-28 4 views
0

Thread.Timers에 대한 MSDN 예제 (http://msdn.microsoft.com/en-us/library/swx5easy.aspx)를 자체 코드로 구현하려고합니다.다른 클래스의 스레드 타이머 취소

특정 사용자 작업이 수행 될 때 타이머를 취소 할 수 있기를 원하지만 타이머를 처리 할 수 ​​없습니다. 다른 클래스의 메서드를 호출하므로 조정할 필요가 있습니다. 그러나 나는 어디 있는지 모른다.

이외의 타이머가 정상적으로 작동합니다. btnconfigOpenConfig가 호출 될 때 왜 내 타이머가 취소되지 않는지 알 수 있습니까?

FYI 저는 작업자 프로세스를 시간 초과 이벤트로 변환합니다. 한스는 의견에서 지적

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의 * 새 * 개체를 만듭니다. 그럴 수는 없지만 클래스에 비공개 필드를 추가하십시오. –

+0

to TimerStateObjClass? TimerStateObjClass 유형의 – Damo

+0

입니다. –

답변

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되어 있지만, 각 실행 후 다시 트리거됩니다.