7

I want to prohibit reentrancy for large set of methods.

for the single method works this code:

bool _isInMyMethod;
void MyMethod()
{
    if (_isInMethod)
        throw new ReentrancyException();

    _isInMethod = true;
    try
    {
        ...do something...
    }
    finally
    {
        _isInMethod = false;
    }
}

This is tedious to do it for every method.
So I've used StackTrace class:

        public static void ThrowIfReentrant()
        {
            var stackTrace = new StackTrace(false);
            var frames = stackTrace.GetFrames();
            var callingMethod = frames[1].GetMethod();
            if (frames.Skip(2).Any( frame => EqualityComparer<MethodBase>.Default.Equals(callingMethod,frame.GetMethod())))
                throw new ReentrancyException();
        }

It works fine but looks more like a hack.

Does .NET Framework have special API to detect reentrancy?

Pavel Voronin
  • 13,503
  • 7
  • 71
  • 137
  • 2
    Why do you care about reentrancy? – John Saunders Dec 14 '12 at 15:20
  • Write code where reentrance is expected, then you can reenter it. – Jodrell Dec 14 '12 at 15:36
  • Legacy code. We have tons of interdependencies between windows. Single action can cause many unnecessary repetetive cascades of events, updates, db requests. And It's hard to detect every such loop with one's eyes. – Pavel Voronin Dec 14 '12 at 15:37
  • 2
    You can take a look on PostSharp. Your situation fits in to be solved by aspect oriented programming (AOP). – Ikaso Dec 14 '12 at 15:41
  • +1 for PostSharp, -1 for exploring the stacktrace (performance penalty), but fortunately, you don't feel comfortable with that yet:) – Steve B Dec 14 '12 at 15:44
  • @SteveB I hope we will remove these checks after refactoring which is in progress now. – Pavel Voronin Dec 14 '12 at 15:48
  • Not the question but on properties I save the input and answer and return the saved answer if the input does not change. In WPF with binding and properties that are input to properties I could not get around multiple calls to get. – paparazzo Dec 14 '12 at 16:04

2 Answers2

3

I recommend using PostSharp to solve your problem. Although it might be expensive to use commercial tool only for a specific reason I suggest you take a look since this tool can solve other problems better suited to be solved by AOP (logging, transaction management, security and more). The company web site is here and you can take a look on examples here. Pluralsight has a good course on the AOP methodology with examples in PostSharp here. Good luck!

Ikaso
  • 2,268
  • 19
  • 26
  • Yes, we have many things to do. I'm interested in PostSharp and have it in my learning plan. But we probably will start with AOP in the form of dynamic interception...later, after adopting appropriate DI container.=) – Pavel Voronin Dec 14 '12 at 16:01
  • @voroninp - do you mean you intend to use tools like dynamic proxies and such? – Ikaso Dec 14 '12 at 16:06
  • @voroninp - I don't think there is something wrong with this approach. It depends on the requirements. There are upsides and downsides to each approach. – Ikaso Dec 14 '12 at 16:11
  • @voroninp - if my answer helped you I would appreciate if you will mark it as an answer. – Ikaso Dec 22 '12 at 12:37
1

The normal .Net approach is to use some for of synchronization to block other threads, rather than make them throw an exception.

Jodrell
  • 34,946
  • 5
  • 87
  • 124
  • That won't help. It does not the matter of async operations. We just have finite cycles of events: A fires then B catches, does something, raises event handled by C and C does something with A what causes A to raise event again. – Pavel Voronin Dec 14 '12 at 15:42