2011-02-15 5 views
0

네트워크에서 여러 서버의 WMI를 통해 정보를로드하는 C# 서비스가 있습니다. 각 서버가 내 ServerInfo 클래스의 인스턴스로 표시되도록 설정했습니다. 메인 프로그램에서 서버의 ArrayList를 통해 구성 및 루프를 초기화하고 ThreadPool.QueueUserWorkItem을 사용하여 작업자 스레드를 시작하여 각 서버를 초기화하거나 업데이트합니다.완료된 스레드의 System.Timers.Timer 이벤트

구성에서 지정한 시간이 지난 후에 백그라운드에서 각 서버를 새로 고치고 싶습니다. 첫 번째 생각은 각 서버 인스턴스에 System.Timers.Timer 개체를 설정하고 스레드 새로 고침 메서드가 완료되면 타이머를 시작하는 것입니다. 주 프로그램은 경과 된 이벤트를 기다리고 해당 서버 인스턴스의 새로 고침 메소드를 다시 시작합니다.

그러나 일단 워커 스레드가 완료되면 타이머가 죽어서 경과 이벤트를 보내지 않는 것처럼 보입니다 (개체가 더 이상 아무 것도 처리하지 않으므로 명백한 것처럼 보입니다).

이와 같은 업데이트를 트리거하려면 어떻게해야합니까?

+1

'Timer'가 "죽어 가고있다"고 생각하는 곳에 [간단한 예제] (http://sscce.org)를 제공해주십시오. 일반적으로'Timer'는'Timer'를 만든 스레드가 없어지더라도 (그 스레드가 주 스레드가 아니면) 할당 한 메서드를 계속 호출해야합니다. – Kiril

답변

0

글쎄, 내 생각은 ServerInfo 클래스가 내부적으로 업데이트를 처리하도록하는 것입니다. ServerInfo 생성자는 타이머를 시작하거나 QueueUserWorkItem을 사용하여 업데이트 스레드를 시작할 수 있습니다. 그렇게하면 주 프로그램의 모든 업데이트 논리를 관리 할 필요가 없습니다.

ServerInfo 클래스에는 주 프로그램이 업데이트를 수신하기 위해 구독하는 이벤트가있을 수 있습니다.

타이머를 시작하기 위해 작업자 스레드를 대기시킬 필요는 없습니다. 메인 스레드 (즉, ServerInfo의 생성자)에서 수행하십시오.

당연히 내가하려는 것은 100 % 명확하지 않으므로 상황에 맞지 않을 수 있습니다.

0

System.Timers.Timer는 Windows 메시지를 사용할 때 예상대로 작동하지 않으므로 스레드에없는 메시지 펌프가 필요합니다. 대신 System.Threading.Timer를 살펴보십시오.

하지만 내 주요 대답은 크리스 호건의 반대입니다. 개체 안쪽에 스레딩을하지 말고 주 응용 프로그램 코드 또는 적어도 하나의 계층에서 수행하십시오.

그래서 .. 모든 ServerInfo를 생성합니다.이 시점에서 컴퓨터 이름과 같은 메타 데이터 만 포함됩니다.

그런 다음 System.Threading.Thread를 사용하여 별도의 스레드를 실행하고 ServerInfo의 ArrayList를 잠그고 ArrayList의 복사본을 가져온 다음 반복하여 각 ServerInfo에서 Update() 메서드를 호출합니다.

각 업데이트 후에 이벤트를 실행하거나 이벤트가 모두 업데이트 된 후에 이벤트를 실행할 수 있습니다.

메인 스레드의 ServerInfo.Updated 이벤트 처리기에서 호출을 마샬링하는 것을 잊지 마십시오! 그렇지 않으면 다음 업데이트주기를 보류하게됩니다. UI 속성을 변경하려면 요구 사항입니다.

+0

** 틀린 **. WinForms.Timer만이 메시지를 사용합니다. 타이머. 티머는 그렇지 않습니다. – SLaks

관련 문제