Click here to Skip to main content
15,886,519 members
Articles / Programming Languages / C#
Article

Easy to check recursion

Rate me:
Please Sign up or sign in to vote.
1.62/5 (4 votes)
9 Oct 20062 min read 22.1K   7   3
Easy to check recursion

Introduction

(This article is translate version , original version written in chinese , you can see it at http://www.cnblogs.com/xdesigner/archive/2006/08/02/465483.html )
  I bring out a easy to check recursion , just call an universal function .

  When we develop complex software , maybe handle recursion , for example , some code modify object1's data , then object2's data has been modified automatic . but when code modify object2's data , then object1's data has been modified automatic too , so there are a recursion , if this recursion is un-control , then system must throw out StackOverflowException . I think somebody must meet this thing .
  Against this recursion cycle , It is nature to define a flag variable and use this variable to check recursion . When system modify object1's data , before modify , check this flat , if this flat has been set , then cancel modify operation , else , set this flag , modify object1's data , after modify operation , clear this flag . In this way , you can check recursion and avoid recursion cycle .
  But in this way , you must define flag varible and maintains this flag , when system modify object's data and throw out exception , forget clear flag, then system can not modify object's data for ever.This is not expediently .
  At there , I bring out a method to resolve this proplem . In fact , we can use system callback stack to check resursion . In .net software , we can get current thread's call stack from  type System.Diagnostics.StackTrace . StackTract's FrameCount property means stack layer count , and GetFrame function returns StackFrame object which maintains single stack layer's information , we can enumerate all call stack and check recursion . So I write a universal function to check recursion as following

C#
/// <summary>
/// Check the parent function has recursion
/// </summary>
/// <returns>If recursion return true , else return false </returns>
public static bool CheckRecursion()
{
    System.Diagnostics.StackTrace myTrace = new System.Diagnostics.StackTrace();
    // If stack layer count less 3 , recursion impossible.
    if (myTrace.FrameCount < 3)
        return false;
    System.IntPtr mh = myTrace.GetFrame(1).GetMethod().MethodHandle.Value;
    for (int iCount = 2; iCount < myTrace.FrameCount; iCount++)
    {
        System.Reflection.MethodBase m = myTrace.GetFrame(iCount).GetMethod();
        if (m.MethodHandle.Value == mh)
        {
            return true;
        }
    }
    return false;
}

  you can use this function anywhere , for example

C#
void SomeFunction()// some function can not recursion
{
   if( CheckRecursion())
      return ;
   //........ some code
}

  We can expend this function , for example , where an universal function to return how many times recursion.
  This function is easy to use , but I test that it is run slowly , so I suggest you can not use it continual . When you must check recursion continual , you have to define flag variable and check recursion fast .

  XDesigner Studio ( http://www.xdesigner.cn/default-eng.htm ) 2006-10-10

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer duchang soft
China China
yuan yong fu of duchang soft , come from CHINA , 2008 Microsoft MVP,Use GDI+,XML/XSLT, site:http://www.cnblogs.com/xdesigner/

Comments and Discussions

 
GeneralThere is a more efficient way to check this ;-) Pin
cdemez23-May-07 2:05
cdemez23-May-07 2:05 
You can use this class to:

public sealed class RecursionPoint:IDisposable
{
private int _isExecuting = 0;
static private int TRUE = 1;
static private int FALSE = 0;

///
/// Returns true if we are already calling this method (We are in a recursion case)
/// Returns false if we are not in recursion.
///

public bool Enter()
{
return (Interlocked.Exchange(ref _isHandlingNextUserPacket, TRUE) == TRUE);
}

public void Exit()
{
Interlocked.Exchange(ref _isHandlingNextUserPacket, FALSE);
}
}



Usage :

RecursionPoint recursionPoint = new RecursionPoint();

public void myMethod()
{
try
{
if (_recursionPoint.Enter()) return;

...... YOUR CODE ......

}
finally
{
_recursionPoint.Enter();
}
}

Krys

GeneralRe: There is a more efficient way to check this ;-) Pin
Pete O'Hanlon23-May-07 2:47
mvePete O'Hanlon23-May-07 2:47 
GeneralRe: There is a more efficient way to check this ;-) Pin
cdemez23-May-07 21:16
cdemez23-May-07 21:16 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.