2009-09-10 4 views
3

다음 코드를 사용하여 메시지를 보냅니다.처리하는 동안 내 기능이 실패하면 System.MessageQueue (MSMQ) 메시지가 손실됩니까?

var transaction = new MessageQueueTransaction()) 
transaction.Begin(); 

var message = new Message 
{ 
    Body = myContent, 
    Recoverable = true 
}; 

m_oMessageQueue.Send(message , myTransaction); 

transaction.Commit(); 

그리고 BeginRecieveReceiveCompleted 이벤트 처리기를 사용하여 메시지를 수신합니다.

EndRecieve를 호출하기 전에 내 이벤트 핸들러가 실패한 경우 메시지가 대기열에 남아 있고 후속 호출에서 수신 할 수 있어야합니까? 내가 보는 행동은 메시지가 영원히 사라 졌다는 것입니다. (또는 어쩌면 다시 사용할 수있게 될 시간 초과가 있습니까?)

업데이트 메시지를받는 코드는 다음과 같습니다.

var messageQueue = new MessageQueue(myPath); 
messageQueue.ReceiveCompleted += messageQueue_ReceiveCompleted_ThrowException; 
messageQueue.BeginReceive(); 

테스트 목적으로 messageQueue_ReceiveCompleted_ThrowException 이벤트 처리기에 예외가 발생합니다.

그런 다음 작동하는 이벤트 처리기로 위 코드를 반복하지만 호출되지 않습니다.

+0

무엇 큐의 EnableConnectionCache로 설정 수신하여입니까? –

+0

나는 그것을 아무 것도 설정하지 않았다, 그것은 무엇을위한 것인가? – tpower

답변

9

문제는 트랜잭션 대기열에 BeginReceive을 사용하고있는 것 같습니다. From MSDN :

주 거래와 비동기 전화 BeginReceive를 사용하지 마십시오. 당신이 트랜잭션 비동기 작업을 수행 BeginPeek를 호출하고 트랜잭션 및 (동기)를 넣어 이벤트 핸들러 내 방법 을 수신하려면 당신은 슬쩍 작업을위한 만듭니다. 이벤트 처리기에 다음 C# 코드에 표시된 과 같은 기능이 포함될 수 있습니다. 이 같은 실패에 대한

, 나는 메시지는 일반적으로 구성 방법에 따라, 부정 승인을 죽은 편지 대기열로 이동하거나 생산 믿는 MessageQueue (당신이 그들을보고하지 않는 이유를 설명 할 수있는). 당신은 read more about those options here 일 수 있습니다.

+0

고맙습니다. 저를 도와주세요. 또 다른 관련 질문으로, 내가 Peek을 사용한다면 메시지가 여러 소비자에 의해 선택 될 가능성이 있습니까? – tpower

+1

여러 소비자가 메시지를 '엿보기'할 수 있지만 실제로는 하나만 특정 메시지를 '수신'할 수 있습니다. 아마도 두 명의 소비자가 동시에있을 수 있기 때문에 약간의주의가 필요할 것입니다. 특정 메시지 (Peek가 발견 한 메시지) 또는 오래된 메시지를 검색하는지 여부를 결정해야합니다. 실패자가 영원히 차단되지 않도록 'Receive' 호출에 타임 아웃을 추가하십시오. –

+0

PeekCompleted에서 전달 된 Id를 사용하여 BeginPeek을하고 나중에 ReceiveById를 사용하는 것이 더 나은 방법일까요? –

2

가장 쉬운 해결 방법은 BeginPeek 또는 Peek을 사용하여 메시지의 내용을 큐에서 제거하지 않고 메시지를 읽은 다음 메시지가 처리 된 후에 큐에서 메시지를 꺼내는 것입니다.