2011-10-03 7 views
1

나는 이벤트 및 대리인을 사용하여 내 rustiness 인해 생각하는 프로그래밍 문제가 있어요 ...Timer가 연결된 객체에 액세스하려면 어떻게합니까?

코드가 :

public void DoStuff() 
     { 
      List<IProcess> processorsForService1 = processorsForService1 = ProcessFactory.GetProcessors(); 

      foreach (IProcess p in processorsForService1) 
      { 
       if (p.ProcessTimer != null) 
       { 
        p.ProcessTimer.Elapsed += new ElapsedEventHandler(IProcess_Timer_Elapsed); 
       } 
      } 
     } 

및 :

 private void IProcess_Timer_Elapsed(object sender, ElapsedEventArgs e) 
      { 
       IProcess p = (IProcess)sender; 
       p.Step_One(); 
       p.Step_Two(); 
      } 

때 첫 번째 줄에 p에 대한 null 참조 예외가 발생하는 이벤트 핸들러에 도착합니다.

이 인스턴스에서 인수를 처리기에 전달하는 방법은 무엇입니까?

+2

그런 식으로 작동하지 않습니다. 객체는 자신이 속한 클래스를 알지 못합니다. 보낸 사람은'타이머 '이며'IP 프로세스'는 아닙니다 –

+0

그래서 p를 이벤트 처리기에 전달할 수 있습니까? 5000 밀리 초마다 각 IProcess 클래스에서 무언가를 호출해야합니다. – Exitos

+1

왜 각 프로세스가 자체 타이머를 대신들을 수 없습니까? –

답변

1

당신은 당신이 경우, 클래스의 원하는 인스턴스가 될 수하는 state 객체, 즉 타이머의 '주인'을 통과 할 수있는 System.Threading.Timer을 사용한다면 당신이하는 System.Timers.Timer을 사용하고있는 것 같습니다. 다음과 같이 이러한 방법으로, 당신은 이벤트 핸들러 내에서 구현의 이전 경험으로 당신의 메소드 본문을 정의 만 지금 서명은 다음과 같습니다

private void MyTimerCallbackMethod(object state) 
{ 

} 

을 그리고, 타이머 인스턴스를 만들 때, 당신은 같은 뭔가를 할 수 :

var timerCallback = new TimerCallback(MyTimerCallback); 
var timer = new Timer(timerCallback, myStateObject, 
    Timeout.Infinite, Timeout.Infinite); 

그런 다음 timer.Change(whenToStart, interval)을 사용하여 타이머를 시작하십시오.

0

보낸 사람은 처리 대리자와 연결된 개체가 아닌 타이머 개체입니다. 처음에는 이벤트가 여러 핸들러를 가질 수 있습니다.

변수 캡처를 사용하여 IProcess에 액세스 할 수있는 대리인을 만들 수 있습니다.

0

델리게이트 대신 람다를 사용하면 참조 환경에 있기 때문에 람다의 클래스를 참조 할 수 있습니다. 나는 이것이 Closure이라고 생각합니다.

public void DoStuff() 
{ 
    List<IProcess> processorsForService1 = ProcessFactory.GetProcessors(); 
    foreach (IProcess p in processorsForService1) 
    { 
     if (p.ProcessTimer != null) 
     { 
      p.ProcessTimer.Elapsed += (s, e) => 
      { 
       p.Step_One(); 
       p.Step_Two(); 
      }; 
     } 
    } 
} 

(msdn 찍은) 비록 다음 범위의 관련 규칙에주의 :

다음 규칙

람다 식에서 변수 범위에 적용

  • 포착 변수 그것을 참조하는 대리인이 범위를 벗어날 때까지 가비지 수집되지 않습니다.

  • 람다 식에 도입 된 변수는 외부 메서드에서 볼 수 없습니다.

  • 람다 식은 둘러보기 방법에서 ref 또는 out 매개 변수를 직접 캡처 할 수 없습니다.

  • 람다 식의 return 문은 둘러싼 메서드를 반환하지 않습니다.

  • 람다 식은 goto 문, break 문 또는 continue 문을 포함 할 수 없습니다. 대상이 본문 외부 또는 포함 된 익명 함수 본문에 포함될 수 없습니다.

0

하면 이벤트 핸들러에게 아이 프로세스의 멤버를 확인하고 다음과 같이 설정 :

p.ProcessTimer.Elapsed += new ElapsedEventHandler(p.IProcess_Timer_Elapsed); 

를하고 다른 곳에서 이벤트를 처리 할 경우, 핸들러는 이벤트 전달합니다

class IProcess 
{ 
    public delegate void Timer_Elapsed_Handler (IProcess process, ElapsedEventArgs e); 
    public event Timer_Elapsed_Handler Timer_Elapsed; 

    public void IProcess_Timer_Elapsed (object sender, ElapsedEventArgs e) 
    { 
    if (Timer_Elapsed != null) Timer_Elapsed (this, e); 
    } 
} 
관련 문제