Reputation: 1895
I am working on a library where the entry points methods are labeled with some attribute. The internal methods need to know whether the original attribute on the entry point has a value of 1
, 2
, 3
...
[MyAttribute(1)]
public void Method1() {
InternalMethod();
}
[MyAttribute(2)]
public void Method2() {
InternalMethod();
}
[MyAttribute(3)]
public void Method3() {
InternalMethod();
}
The only way that I know to get the attribute is to traverse the stack up to the root and search for a method that has the MyAttribute
attribute. The problem with this approach is that I am implementing it using the StackTrace
class, which is too expensive as the methods are called during frequent HTTP
requests that need to be as fast as possible.
Is there any way around this?
Upvotes: 1
Views: 1162
Reputation: 1500175
Assuming that:
InternalMethod
would only have one attribute in its stack trace (you don't have multiple calls from different places that then call InternalMethod()
with different attribute values elsewhere in the stack)If those assumptions are true, I have a pretty hacky suggestion...
Change the InternalMethod
signature to
void InternalMethod([CallerFilePath] string file = null, [CallerLineNumber] int line = 0)
At that point, your InternalMethod()
calls will get the path and line number arguments populated automatically by the compiler. That doesn't help you get the attribute - but it does mean you can perform the stack crawl for that call site once, and then populate a cache based on that file/line number combination. As a first pass, you could just cache based on $"{file}:{line}"
, but if you want even higher performance, you'd avoid the string concatenation via a more complicated cache.
Note that the compiler provides the file and line number, so it doesn't matter whether it's a release build, or if the method is inlined, etc.
Upvotes: 2