2012-01-09 3 views
1

타임 아웃 메시지가 수신 될 때까지 특정 유형의 수신 메시지를 추적하기 위해 사가를 사용하는 에이전트가 있습니다. 타임 아웃 처리기에서 나는 다음과 같습니다Bus.Publish() 또는 subscription에 의해 StackOverflowException이 발생 했습니까?

[Serializable] 
    public class TransactionDetail 
    { 
     // Guid needed for NHibernate to store it in database. All 
     // member variables are virtual for the same reason. 
     public virtual Guid Id { get; set; } 
     public virtual Int32 ScheduleBatchID { get; set; } 
     public virtual Int32 PseudoSagaID { get; set; } 
     public virtual String CreditCardNumber { get; set; } 
     public virtual String ExpiryDate { get; set; } 

     public virtual String AccountNumber { get; set; } 
     public virtual String BSB { get; set; } 

     public virtual Decimal Amount { get; set; } 
     public virtual Int32 Firm_fk { get; set; } 
     public virtual String FirmName { get; set; } 
     public virtual TransactionType PaymentType { get; set; } 
     // transaction number, max 15 chars, to use one of the following: 
     public virtual int ApplicationPaymentInfo_fk { get; set; } 
     public virtual BankRequestResponseSagaBase Parent { get; set; } 
    } 

내가 자리에있는 구독이없는 경우 버스 :

public override void Timeout(object state) 
     { 
      // If Data.IsNull: Do nothing!!! Report to log only. 
      Logger.Debug("========================================================================="); 
      Logger.Debug(string.Format("Timeout message received. State: {0}.", state.ToString())); 

      QuickBatch qbBuilder = new QuickBatch(); 
      // Create new message and publish it 
      BankRequestBatchClosed eventMessage = Bus.CreateInstance<BankRequestBatchClosed>(); 

      eventMessage.UniqueBatchIdentifier = qbBuilder.GenerateUniqueBatchIdentifier(QuickBatch.QB_BATCHTYPE_CC); 
      eventMessage.ScheduleBatchID = this.Data.ScheduleBatchID; 
      eventMessage.EventDate = DateTime.Now; 
      eventMessage.EventID = Guid.NewGuid(); 
      eventMessage.TransactionItems = this.Data.PaymentRequestedTransactionItems; 

      Logger.Debug("========================================================================="); 
      Logger.Debug(string.Format("Timeout method about to send BankRequestBatchClosed message. UniqueBatchIdentifier: {0}",eventMessage.UniqueBatchIdentifier)); 

      Bus.Publish(eventMessage); 
      Complete(); 
     } 

TransactionItems하는 ICollection은 여기

는 TransactionDetail 클래스입니다 .Publish() 호출은 정상적으로 처리됩니다.

가 'System.StackOverflowException'형식의 처리되지 않은 예외가이 이외의 오버 플로우에 대한 더 이상의 정보가 없습니다 mscorlib.dll에서

에서 발생

: 나는 다른 서비스가에 가입 한 경우에, 나는 다음과 같은 오류 메시지가 : {현재 스레드가 스택 오버 플로우 상태에 있기 때문에 표현식을 계산할 수 없습니다.}

내 자신의 SagaPersister, 프로필 및 SagaRegistry를 가지고 있지만이 문제와 관련이 있는지는 확실하지 않지만 필요한 경우 제공 할 수 있습니다.

답변

2

여기에 약간의 의심스러운 한 가지가 BankRequestResponse입니다 호출 SagaBase TransactionDetail 개체의 부모 속성입니다. 사가 끈질긴 소란을 일으키는 참고 문헌에 반복문이있을 수도 있습니다.

+0

참고 문헌을 삭제하고 몇 줄의 다른 줄을 정리하면 충돌이 멈췄습니다. Udi에게 감사 드리며, 시드니에서 당신을 만나려고합니다. – Fellmeister

2

스택 오버플로는 일반적으로 재진입 코드 (직접 간접적으로 호출하는 메소드)에 의해 발생합니다. 메소드가 호출 될 때마다 스택에서 조금 더 많은 공간을 사용하므로 자신을 호출하면 모든 스택을 사용하는 무한 루프).

.net에 버그가있을 수 있지만 TimeOut 이벤트 처리기가 다른 호출을 발생시키는 첫 번째 호출을 처리하는 동안 Timeout에 대한 다른 호출을 발생시키는 것일 가능성이 높습니다. , 무한 루프가 발생합니다. 출력 로그에 "Timeout received"텍스트가 대량으로 생성되고 있습니까? 이러한 상황을 방지하기

방법은 다음과 같습니다

  • 이 어떤 작업을 수행하기 전에 이벤트 처리기에서 이벤트 구독을 제거 (및 출구에 그것을 다시 가입 재진입
  • 의 원인이 전화를하지 마십시오
  • 가 재진입 감지하는 부울 변수 또는 다른 연동 사용) 핸들러에서하는 것은
+0

당신은 내가 작성한 다른 응용 프로그램에서 유용했습니다. 그것을 공유하는 데 시간을내어 주셔서 감사합니다. – Fellmeister

관련 문제