개인, 로컬 메시지 큐 (MSMQ)를 처리하는 Windows 서비스가 있습니다. 시작될 때 큐에 PeekCompleted
에 대한 이벤트 처리기를 등록한 다음 비동기 BeginPeek()
을 호출하여 메시지가 도착하기를 기다립니다.BeginPeek을 사용한 후에 EndPeek에 전화해야합니까?
protected override void OnStart(string[] args)
{
if (String.IsNullOrWhiteSpace(args[0]))
return;
queue = new MessageQueue(args[0]);
queue.Formatter = new BinaryMessageFormatter();
queue.PeekCompleted += new PeekCompletedEventHandler(OnPeekCompleted);
queue.BeginPeek();
}
일단 메시지가 도착하면, 분명히 그 메시지를 처리하는 것이 목표입니다. 내 코드는 현재 트랜잭션 내에 포함 된 메시지를 가져 오는 queue.Receive()
메서드를 가지고 있으므로 처리 중에 오류가 발생하면 메시지가 대기열에 다시 저장됩니다. BeginPeek()
이 다시 호출되어 사이클을 다시 시작합니다.
private static void OnPeekCompleted(Object source, PeekCompletedEventArgs asyncResult)
{
try
{
MessageQueue q = (MessageQueue)source;
using (MessageQueueTransaction trans = new MessageQueueTransaction())
{
trans.Begin();
Message msg = q.Receive(trans);
ProcessMessage(msg);
trans.Commit();
}
// Restart the asynchronous peek operation.
q.BeginPeek();
}
catch (MessageQueueException qEx)
{
// TODO: Walk it off.
}
return;
}
마 내가 어떤 시점에서, 큐에 EndPeek()
를 호출 할 필요가?
this question과 같은 메모리 누출을 피할 수 있습니까? 나는 그럴 필요가 없다고 확신하지만 문서화는 그다지 명확하지 않다. 그것은 단지 그것을 끝내지 않고 무언가를 '시작'하는 것을 100 % 올바르게 느끼지 못한다. :)
Btw : 줄을 Message msg = q.EndPeek(asyncResult.AsyncResult)
으로 바꿀 수 있는데, 나는 똑같이 메시지를 가져 오지만, 메시지를 가져 오지는 않는다. 대기열의 메시지
'.EndPeek() '을 호출하지 않는 이유가 있습니까? '.EndPeek()'의 결과를 필요로하지 않는다면, 그것을 버릴 수는 있지만, 전혀 호출하지 않는 것은 거의 나쁜 생각입니다. 여러분은 본질적으로'.BeginPeek()'에 뱅킹하고 있습니다. '.EndPeek()'이 해제해야하는 관리되지 않는 리소스를 할당합니다. 그것이 사실 일지라도, 누가 다음 릴리스가 그 가정을 깨뜨리지 않을 것이라고 말합니까? –
사이드 노트 : pleinolijf, 내 게시물이 "내 코드가 틀린 것처럼 보입니다. 신뢰할 수있는 기회가 될 수 있습니다."와 같이 읽습니다. 개인적으로 코드의 정확성에 관계없이 그렇게하지는 않을 것입니다. 미래의 모든 독자가 EndXXXX 코드를 찾거나 수정하는 데 낭비되는 시간이 낭비 될 것입니다. –
공정한 점수, 둘 다. 그리고 그것은 본질적으로 제가 요구하는 것입니다 : EndPeek에 전화하지 않는 것이 안전할까요? BeginPeek은 실제로 어떤 자원을 할당합니까? 분명히 나에게 불명확 한 것은, 비록 분명히 방법의 이름이 그것을 암시하지만. 내가 찾고있는 건 사실이 아니라 가정이다. – pleinolijf