C# Bus.Publish()或订阅导致StackOverflowException?

C# Bus.Publish()或订阅导致StackOverflowException?,c#,msmq,nservicebus,saga,C#,Msmq,Nservicebus,Saga,我有一个代理,它使用saga跟踪给定类型的传入消息,直到收到超时消息。在超时处理程序中,我有以下内容: public override void Timeout(object state) { // If Data.IsNull: Do nothing!!! Report to log only. Logger.Debug("======================================================

我有一个代理,它使用saga跟踪给定类型的传入消息,直到收到超时消息。在超时处理程序中,我有以下内容:

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();
        }
如果我没有任何订阅,那么Bus.Publish()调用将正常进行。如果我订阅了其他服务,我会收到以下错误消息:

mscorlib.dll中发生类型为“System.StackOverflowException”的未处理异常

除此之外,没有关于溢出的其他信息:{无法计算表达式,因为当前线程处于堆栈溢出状态。}


我有自己的SagaPersister、Profile和SagaRegistry,但不确定它们是否与此问题相关,但如果需要,可以提供它们。

堆栈溢出通常是由重入代码引起的(一种可能间接调用自身的方法。每次调用一个方法时,它都会在堆栈上占用更多的空间,因此,如果它调用自身,它可以创建一个无限循环,从而耗尽所有堆栈)

.net中可能存在错误,但更有可能的是,您的超时事件处理程序在处理第一个调用时调用了另一个超时调用,从而导致另一个调用,以此类推,从而导致无限循环。您的输出日志中是否收到了大量的“接收超时”文本

避免这种情况的方法有:

  • 不要打导致重入的电话
  • 在事件处理程序执行任何工作之前,请删除事件处理程序中的事件订阅(并可能在退出处理程序时重新订阅)
  • 使用bool变量或其他联锁来检测重入调用

堆栈溢出通常是由重入代码(一种可能间接调用自身的方法。每次调用一个方法时,它都会在堆栈上占用更多的空间,因此如果它调用自身,则会创建一个无限循环,从而耗尽所有堆栈)

.net中可能存在错误,但更有可能的是,您的超时事件处理程序在处理第一个调用时调用了另一个超时调用,从而导致另一个调用,以此类推,从而导致无限循环。您的输出日志中是否收到了大量的“接收超时”文本

避免这种情况的方法有:

  • 不要打导致重入的电话
  • 在事件处理程序执行任何工作之前,请删除事件处理程序中的事件订阅(并可能在退出处理程序时重新订阅)
  • 使用bool变量或其他联锁来检测重入调用

    • 这里看起来有点可疑的一件事是TransactionDetail对象上的BankRequestResponseSagaBase父属性。可能是您的引用中有一个循环导致您的saga persister崩溃。

      这里看起来有点可疑的一件事是您的TransactionDetail对象上的BankRequestResponseSagaBase父属性你的TransactionDetail对象。可能是你的引用中有一个循环导致你的传奇持久器爆炸。

      我删除了那里的引用并整理了其他几行,它停止了崩溃。谢谢Udi,我将尝试到悉尼来看你。我删除了那里的引用并整理了其他几行,它停止了PPD崩溃。感谢Udi,我将尝试在悉尼与您见面。您的rpost在我编写的另一个应用程序中非常有用。感谢您花时间共享它。您的rpost在我编写的另一个应用程序中非常有用。感谢您花时间共享它。
         [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; }
          }