2013-09-02 3 views
2

함수를 재귀 적으로 호출해야합니다. 그러나 잠시 후 StackOverFlowException을 던집니다. Invoke (새 Action (Start)) 메서드를 사용하면 긴 예외가 아니라 동일한 예외가 발생하지만 이전 메서드보다 짧습니다.재귀 함수 호출 Throw StackOverFlowException

이 문제를 어떻게 극복 할 수 있습니까?

예제 코드 :

private void Start() 
     { 
      // run select query 
      mysql(selectQueryString.ToString()); 
      msdr = mysql(); 
// is finished 
      if (!msdr.HasRows) 
      { 
       this.Finish(); 
       return; 
      } 
      // get mysql fields 
      string[] mysqlFields = Common.GetFields(ref msdr); 
      while (msdr.Read()) 
      { 
       // set lastSelectID 
       lastSelectID = Convert.ToInt32(msdr[idFieldName].ToString()); 
       // fill mssql stored procedure parameters 
       for (int i = 0; i < matchTable.Count; i++) 
       { 
        string valueToAdd = Common.ConvertToEqualivantString(matchTable[i].Type, matchTable[i].Value, ref msdr, ref id, matchTable[i].Parameters); 
        sql.Ekle(matchTable[i].Key, valueToAdd); 
       } 
       // execute adding operation 
       lastInsertID = (int)sql(false); 
       // update status bar 
       this.UpdateStatusBar(); 
// update menues 
       this.UpdateMenues(); 
       // increment id for "{id}" statement 
       id++; 
      } 
// close data reader 
      msdr.Close(); 
      msdr.Dispose(); 
      mysql.DisposeCommand(); 
// increment select limit 
      selectQueryString.LimitFirst += selectQueryString.LimitLast; 
      // call itself until finish 
      this.Start(); 
     } 
+0

얼마나 많은 재귀를 기대합니까? 물론 당신은 결국 스택을 날려 버릴 것입니다. 재귀를 멈추게하는 조건은 없습니다. 내가 볼 수있는 한 영원히 계속됩니다. –

+0

@SimonWhitehead 종료 조건은 메소드의 맨 위에 있습니다. 조기 반환. 그러나 조건은 나에게 좋은 것처럼 보이지 않는다. 편집 : 나는 그것에 대해 잘못했다. mysql()은 매번 다른 것을 반환한다. – hvd

+0

// 선택 증가 제한 selectQueryString.LimitFirst + = selectQueryString.LimitLast; – Mesut

답변

12

함수의 마지막 문은 함수 자체에 대한 호출이 스택 오버 플로우 예외를 피하기 위해 꼬리 재귀 최적화 언어가 있지만, 당신은 C 번호는 tail-recursion.이 그들 중 하나가 아닙니다.

재귀는 임의의 길이가 될 수있는 데이터에 좋은 패턴이 아닙니다. 재귀를 while 루프로 바꾸기 만하면됩니다.

+2

+1은 C# 컴파일러가 꼬리 재귀를 수행하지 않으며이 질문과의 관련성을 언급합니다. –

+0

C#에서는 스택 오버플로가없이 꼬리 호출이 작동한다는 것을 보증하지 않는다고합니다. 적어도 x64에서는 꼬리 호출이 작동합니다. http://stackoverflow.com/questions/15864670/generate-tail-call-opcode – tia