이 배열 내에서 CWorker 클래스는 CWorkerThread 클래스의 구현
을 생성합니다. CWorkerThread
클래스(아래 설명)는 상속되어야 하는 추상 클래스입니다. 내보낸
클래스는 메시지 처리 방법을 정의합니다.
aThreads = new ArrayList()
for;
(int idx=0; idx〈sfWorker.NumberThreads; idx++)
{
WorkerThreadFormatter
wfThread = new WorkerThreadFormatter()
wfThread.PROcessName = sfWorker.ProcessName
wfThread.ProcessDesc = sfWorker.ProcessDesc
wfThread.ThreadNumber = idx;
wfThread.InputQueue = sfWorker.InputQueue
wfThread.ErrorQueue =
sfWorker.ErrorQueue
wfThread.OutputName = sfWorker.OutputName
;
보조 유형을 정의하고 이를 보조 스레드 구조
CWorkerThread
스위치에 삽입합니다.
(sfWorker.ProcessType)
{
사례
WorkerFormatter.SFProcessType.ProcessRoundRobin:
wtBase = new
CWorkerThreadRoundRobin(this, wfThread)
break
case;
WorkerFormatter.SFProcessType.ProcessAppSpecific:
wtBase = new
CWorkerThreadAppSpecific(this, wfThread)
break
case;
WorkerFormatter.SFProcessType.ProcessAssembly:
wtBase = new
CWorkerThreadAssembly(this, wfThread);
중단
기본값:
throw new Exception("알 수 없는 처리 유형");
}
// 배열에 호출 추가
aThreads.Insert(idx, wtBase);
}
모든 개체가 생성되면 각 스레드 개체의 Start 메서드를 호출하여 시작할 수 있습니다.
foreach(CWorkerThread
cThread in aThreads)
cThread.Start();
Stop 메소드에는 다음과 같은 가비지 수집 작업이 있습니다.
GC.SuppressFinalize(this);
를 명시적으로 호출하지 않고도 개체가 올바르게 종료될 수 있습니다. Stop이 호출되면
메서드를 사용하면
생성자를 구문 분석할 필요가 없습니다. SuppressFinalize 메서드는 개체의 Finalize 메서드 호출을 방지합니다(
RoundRobin 및
CWorkerThreadAssembly에서 상속된 추상 클래스입니다. 메시지를 어떻게 처리하든 대부분의 대기열 처리는 동일하므로 CWorkerThread 클래스가 이 기능을 제공합니다.
이 클래스는 리소스를 관리하고 메시지를 처리하기 위한 추상 메서드(실제 메서드로 대체되어야 함)를 제공합니다.
수업 작업은 Start, Stop, Pause 및 Continue 메서드를 통해 다시 한 번 수행됩니다.
메시징 네임스페이스:
// 대기열을 열고 기본 읽기 및 쓰기 속성을 설정해 보세요.
MessageQueue mqInput = new MessageQueue(sInputQueue);
mqInput.MessageReadPropertyFilter.Body = true;
mqInput.MessageReadPropertyFilter.AppSpecific = true
MessageQueue;
mqError = new MessageQueue(sErrorQueue)
// MSMQ COM을 사용하는 경우 포맷터를 ActiveX로 설정합니다.
mqInput.Formatter = 새로운 ActiveXMessageFormatter()
mqError.Formatter =
new ActiveXMessageFormatter();
메시지 대기열 참조가 정의되면 실제 처리 기능인
네임스페이스를 사용하면 스레딩을 쉽게 구현할 수 있습니다.
procMessage = new Thread(new
ThreadStart(ProcessMessages));
procMessage.Start();
ProcessMessages 함수는 부울 값을 기반으로 하는 처리 루프입니다. 값이
값만 설정한 다음 열린 메시지 대기열을 닫고 스레드를 기본 스레드와 조인합니다.
// 서비스 스레드 및 처리 스레드 조인
bRun =
false;
procMessage.Join();
//열린 메시지 대기열 닫기
mqInput.Close();
mqError.Close();
Pause 메소드는 처리 스레드를 0.5초 동안 절전 모드로 만들기 위해 부울 값만 설정합니다.
if (bPause)
Thread.Sleep (500) ;
마지막으로 각 Start, Stop, Pause 및 Continue 메서드는 추상
을 구현하는 클래스에 후크를 제공하여 필요한 리소스를 캡처하고 해제합니다.
ProcessMessages 루프의 기본 구조는 다음과 같습니다.
●메시지 수신에 성공하면 추상 ProcessMessage 메서드가 호출됩니다.
●Receive 또는 ProcessMessage가 실패하면 메시지를 오류 대기열로 보냅니다.
Message mInput;
try
{
// 대기열에서 읽고 1초 동안 기다립니다.
mInput =
mqInput.Receive(new TimeSpan(0,0,0,1))
}
catch(MessageQueueException
mqe)
{
// 메시지를 null로 설정
mInput = null
// 오류 코드를 확인하여 시간이 초과되었는지 확인하세요.
if (mqe.ErrorCode != (-1072824293) ) //0xC00E001B
{
//
시간 초과되지 않으면 오류를 발생시키고 오류 번호를 기록합니다.
LogError("Error: " + mqe.Message)
throw mqe;
}
}
if (mInput != null)
{
// 처리할 메시지를 가져와서 메시지 처리 추상 메소드 호출
try
{
ProcessMessage(mInput)
}
// 알려진 비정상 상태의 오류 캡처
catch (CWorkerThreadException ex)
{
ProcessError(mInput,
ex.Terminate);
}
// 알 수 없는 예외를 catch하고 Terminate 호출
catch
{
ProcessError(mInput, true);
}
}
ProcessError 메서드는 오류 메시지를 오류 대기열로 보냅니다. 게다가 다음으로 이어질 수도 있습니다.
스레드를 종료하려면 예외를 보냅니다. ProcessMessage 메서드가 종료 오류나 CWorker
ThreadException 유형을 발생시키는 경우 이 작업을 수행합니다.
CworkerThread 내보낸 클래스
CWorkerThread에서 상속되는 모든 클래스는 OnStart, OnStop, On
Pause, OnContinue 및
프로세스메시지 메서드. OnStart 및 OnStop 메서드는 처리 리소스를 획득하고 해제합니다. OnPause 및 OnContinue
방법을 사용하면 이러한 리소스를 일시적으로 해제하고
재획득할 수 있습니다. ProcessMessage 메서드는 메시지를 처리하고 실패 이벤트가 발생할 때
를 발생시켜야 합니다.
CWorkerThreadException 예외.
생성자를 호출해야 합니다.
public
CWorkerThreadDerived(CWorker v_cParent, WorkerThread
Formatter v_wfThread)
: base (v_cParent, v_wfThread) {}
메서드를 호출하는 두 가지 처리 유형을 제공합니다. 메시지 수신 및 전송 구현 모두 루핑 기술 또는 애플리케이션 오프셋(유지)을 사용합니다.
사용할 대기열을 결정하는 요소로 메시지 AppSpecific 속성에 남겨 둡니다. 이 구성표
의 구성 파일에는 대기열 경로 목록이 포함되어야 합니다. OnStart 구현 및
OnStop 메소드
는 다음 대기열에 대한 참조를 열고 닫아야 합니다.
iQueues = wfThread.OutputName.Length;
mqOutput = new MessageQueue[iQueues];
for (int idx=0; idx〈iQueues;
idx++)
{
mqOutput[idx] = new MessageQueue(wfThread.OutputName[idx]);
mqOutput[idx].Formatter = new ActiveXMessageFormatter();
}
루프의 경우 이 프로세스는 다음과 같습니다.
시도
{
mqOutput[iNextQueue].Send(v_mInput)
}
catch(예외 예)
{
// 오류 발생 시 강제 종료 예외 발생
throw new CWorkerThreadException(ex.Message, true);
// 다음 대기열 번호 계산
iNextQueue++;
iNextQueue %= iQueues;
메시지 매개변수를 사용하여 구성 요소를 호출하는 후자의 방법이 더 흥미롭습니다. 프로세스 메시지
는 이 구성 요소의 참조를 얻고 해제합니다.
이 시나리오의 구성 파일에는 전체 클래스 이름과 클래스가 있는 파일의
객체 참조를 얻으려면 Activator.CreateInstance 메서드를 사용해야 합니다. 이 편지
객체 참조를 얻은 후에는 적절한 인터페이스에 배치됩니다.
private
IWebMessage iwmSample;
개인 문자열 sFilePath, sTypeName>//
어셈블리 경로 및 유형 이름 저장
sFilePath = wfThread.OutputName[0]
sTypeName =
wfThread.OutputName[1];
// 필요한 객체에 대한 참조 가져오기
어셈블리 asmSample =
Assembly.LoadFrom(sFilePath);
유형 typSample = asmSample.GetType(sTypeName);
object objSample = Activator.CreateInstance(typSample)
// 객체에 필요한 인터페이스 정의
iwmSample = (IWebMessage)objSample;
객체 참조를 얻은 후 ProcessMessage 메서드는 IWebMessage 인터페이스에서
Process 메서드를 호출합니다.
WebMessageReturn wbrSample;
try
{
// 메소드 호출을 위한 매개변수 정의
문자열
sLabel = v_mInput.Label;
문자열 sBody = (string)v_mInput.Body
int;
iAppSpecific = v_mInput.AppSpecific
// 메소드 호출 및 반환 코드 캡처
wbrSample =
iwmSample.Process(sLabel, sBody, iAppSpecific)
}
catch
(InvalidCastException ex)
{
// 메시지 내용에 오류가 발생하면 종료되지 않는 예외를 강제 발생
throw
new CWorkerThreadException(ex.Message, false)
}
catch(예외 ex)
{
// 어셈블리가 잘못 호출된 경우 종료 예외를 강제로 발생시킵니다.
throw new
CWorkerThreadException(ex.Message, true);
}
//오류가 없으면 객체 호출의 반환 상태를 확인합니다.
스위치(wbrSample)
{
케이스 WebMessageReturn.ReturnBad:
throw
new CWorkerThreadException
("메시지를 처리할 수 없습니다: 메시지가 표시됨
bad", false);
case WebMessageReturn.ReturnAbort:
throw new
CWorkerThreadException
("메시지를 처리할 수 없습니다: 처리
terminating", true);
기본값:
break;
}
제공된 샘플 구성 요소는 메시지 본문을 데이터베이스 테이블에 기록합니다. 심각한 데이터베이스 오류가 캡처된 경우
오류가 발생하면 프로세스를 종료하고 싶을 수도 있지만 여기서는 메시지를 오류 메시지
로 표시하면 됩니다.
이 예제에서 생성된 클래스 인스턴스는 값비싼 데이터베이스 리소스를 획득하고 보유할 수 있으므로
OnPause 및 OnContinue 메서드를 사용하여 개체 참조를 해제하고 다시 획득합니다.
탐지 장치
모든 좋은 애플리케이션과 마찬가지로 탐지 장치는
애플리케이션 상태를 모니터링하는 데 사용됩니다. . NET Framework는 이벤트 로그, 성능 카운터 및 Windows 관리 계측
장치(WMI) 통합을 크게 단순화합니다.
) 신청 절차에 들어갑니다. 메시징 애플리케이션은 System.Diagnostics 어셈블리의 시간 로그와 성능 카운터를 사용합니다.
EventLog 멤버는 애플리케이션 이벤트 로그에 쓰기를 지원합니다.
EventLog.WriteEntry(sMyMessage, EventLogEntryType.Information);
생성하고 얻을 수 있습니다. 리소스(에서와 같이
CWorker 클래스에서와 동일),
WriteEntry 메소드를 사용하여 로그 항목을 기록할 수 있습니다:
private EventLog cLog;
string sSource = ServiceControl.ServiceControlName
string sLog = "application"
//
소스가 있는지 확인하고 없으면 소스를 생성하세요.
if (!EventLog.SourceExists(sSource))
EventLog.CreateEventSource(sSource, sLog)
// 로그 객체를 생성하고 현재 정의된 소스를 참조합니다.
cLog =
new EventLog();
cLog.Source = sSource
// 성공적인 생성을 나타내는 항목을 로그에 작성합니다.
cLog.WriteEntry("성공적으로 생성됨", EventLogEntryType.Information);
및 메시지를 추적하는 전체 애플리케이션에 대한 카운터를 제공합니다.
초당 처리되는 메시지 수와 메시지 수입니다. 이 기능을 제공하려면 성능 카운터 클래스
를 정의한 다음 해당 카운터 인스턴스를 증가시켜야 합니다.
CounterCreationData[] cdMessage = 새로운 CounterCreationData[2];
cdMessage[0] = new CounterCreationData("메시지/총계", "총
메시지
처리됨",
PerformanceCounterType.NumberOfItems64);
cdMessage[1] = 신규
CounterCreationData("초당 메시지 수",
"1초 동안 처리된 메시지 수",
PerformanceCounterType.RateOfChangePerSecond32);
PerformanceCounterCategory.Create("MSDN 메시지 서비스", "MSDN
메시지
Service Counters", cdMessage);
성능 카운터 범주가 정의되면 PerformanceCounter 개체가 생성되어 액세스됩니다.
선택적 인스턴스 이름이 필요합니다. 도우미 프로세스의 경우 xml 파일의 프로세스 이름이 사용되며 코드는 다음과 같습니다.
pcMsgTotWorker = new PerformanceCounter("MSDN 메시지 서비스",
"메시지/전체", sProcessName)
pcMsgSecWorker = new
PerformanceCounter("MSDN 메시지 서비스",
"메시지/초", sProcessName);
pcMsgTotWorker.RawValue = 0;
pcMsgSecWorker.RawValue = 0;
카운터를 늘리려면 적절한 메서드를 호출하세요.
pcMsgTotWorker.IncrementBy(1);
pcMsgSecWorker.IncrementBy(1);
마지막으로 서비스가 종료되면 설치된 성능 카운터 카테고리가 시스템에서 삭제되어야 합니다.
PerformanceCounterCategory.Delete("MSDN Message Service");
성능 카운터는 .NET Framework에서 작동하므로 특별한 서비스를 실행해야 합니다.
이 서비스(PerfCounterService)는 공유 메모리를 제공합니다. 카운터 정보는 공유
메모리에 기록되고 성능 카운터 시스템에서 읽혀집니다.
설치
마치기 전에 설치 및 installutil.exe라는
설치 도구에 대해 간단히 소개하겠습니다. 이 응용 프로그램은 이후
Windows 서비스인 경우 installutil.exe
를 사용하여 설치해야 합니다. 따라서 System.Configuration.Install에서 하나를 사용해야 합니다.
어셈블리에서 상속된 설치 프로그램 클래스
:
공용 클래스 ServiceRegister: 설치 프로그램
{
개인 ServiceInstaller serviceInstaller
개인 ServiceProcessInstaller;
processInstaller;
public ServiceRegister()
{
// 서비스 설치 프로그램 생성
serviceInstaller = 새로운 ServiceInstaller();
serviceInstaller.StartType = ServiceStart.Manual;
serviceInstaller.ServiceName = ServiceControl.ServiceControl
이름;
serviceInstaller.DisplayName = ServiceControl.ServiceControl
Desc;
Installers.Add(serviceInstaller)
// 프로세스 설치 프로그램 생성
ProcessInstaller = 새로운 ServiceProcessInstaller();
ProcessInstaller.RunUnderSystemAccount = true;
Installers.Add(processInstaller);
}
}
이 예제 클래스에 표시된 것처럼 Windows 서비스의 경우 서비스와 서비스 프로세스에는 각각 하나의
설치 프로그램이 필요합니다. 서비스가 실행되는 계정을 정의합니다. 다른 설치 프로그램에서는 이벤트 로그 등록을 허용하고
성능 카운터와 같은 리소스.
요약
이 .NET Framework 응용 프로그램 예제에서 볼 수 있듯이 과거에는 Visual C++
프로그래머만이 작성할 수 있었던 응용 프로그램을 이제 간단한 객체 지향을 사용하여 작성할 수 있습니다. 프로그램을 달성합니다. 배기가스
C#에 중점을 두고 있지만 이 문서에서 설명하는 내용은 Visual Basic 및
새로운 .NET에도 적용됩니다.
이 프레임워크를 통해 개발자는 프로그래밍 언어를 사용하여 강력하고 확장 가능한 Windows 응용 프로그램 및 서비스를 만들 수 있습니다.
자주 잊어버리는 애플리케이션 계측 장치(예: 성능 모니터링 카운터 및 이벤트 로그 알림)를 쉽게 통합합니다.
앱에 병합되었습니다. 여기 애플리케이션은 Windows 관리 감지 장치
(WMI)를 사용하지 않지만 .NET Framework에서도 이를 적용할 수 있습니다.