Can I add an attribute to a function to prevent re

2019-03-27 19:04发布

At the moment, I have some functions which look like this:

private bool inFunction1 = false;
public void function1()
{
    if (inFunction1) return;
    inFunction1 = true;

    // do stuff which might cause function1 to get called
    ...

    inFunction1 = false;
}

I'd like to be able to declare them like this:

[NoReEntry]
public void function1()
{
    // do stuff which might cause function1 to get called
    ...
}

Is there an attribute I can add to a function to prevent reentry? If not, how would I go about making one? I've heard about AOP attributes that can be used to add code before and after function calls; would they be suitable?

9条回答
Root(大扎)
2楼-- · 2019-03-27 19:27

Without assembly and IL rewriting, there's no way for you to create a custom attribute that modifies the code in the way you describe.

I suggest that you use a delegate-based approach instead, e.g. for functions of a single argument:

static Func<TArg,T> WrapAgainstReentry<TArg,T>(Func<TArg,T> code, Func<TArg,T> onReentry)
{
    bool entered = false;
    return x =>
    {
        if (entered)
            return onReentry(x);
        entered = true;
        try
        {
            return code(x);
        }
        finally
        {
            entered = false;
        }
    };
}

This method takes the function to wrap (assuming it matches Func<TArg,T> - you can write other variants, or a totally generic version with more effort) and an alternate function to call in cases of reentry. (The alternate function could throw an exception, or return immediately, etc.) Then, throughout your code where you would normally be calling the passed method, you call the delegate returned by WrapAgainstReentry() instead.

查看更多
淡お忘
3楼-- · 2019-03-27 19:31

You may find that you could use PostSharp to accomplish this - along with the suggestions from Anthony about using try/finally. It's likely to be messy though. Also consider whether you want the re-entrancy to be on a per-thread or per-instance basis. (Could multiple threads call into the method to start with, or not?)

There's nothing like this in the framework itself.

查看更多
闹够了就滚
4楼-- · 2019-03-27 19:32

I dont think that will be possible.

The closest will be the the 'Synchronized' attribute, but that will block all subsequent calls.

查看更多
登录 后发表回答