Firstly, sorry for the difficult question title, but I can't think of anything better. If anybody knows a better description, I'd be happy to change the title! :)
Let's assume I have the following code with the two classes:
using(new Wrapper())
{
Inner.Do();
}
public class Wrapper : IDisposable
{
public static Wrapper Instance { get; set; }
public Wrapper()
{
Instance = this;
}
public void Dispose()
{
Instance = null;
}
}
public static class Inner
{
public static Do()
{
if (Wrapper.Instance == null)
{ /* no using */ }
else
{ /* with using */ }
}
}
Above code works as intended, and I am able to detect whether or not my code was wrapped up in a using statement or not.
Unfortunately, a static Instance variable is the best way I can think of to achieve the above, but it's certainly not best-case. Assume that two Threads execute above code at the "same" time. One Thread would overwrite the Instance of the other, leading to unexcepted beaviour and race conditions.
Question:
Can anybody direct me to a solution where I am still able to do the above, but without the use of a static Instance variable?
Thanks in advance!
ANSWER
Since this is just a test for something new, I am now using the ThreadStaticAttribute. But as Marc Gravell stated out, don't use this if there are async operations going on.
For usage see Kris Vandermotten's answer.
Personally I would advise simply: not needing to do that. You are right in that there is no magic way to do that. The thread issue can be handled via [ThreadStatic]
, but that won't work well when multiple threads are involved, for example async
. If possible, I would say: find a different implementation strategy that doesn't require detecting unrelated using
blocks. Equally, your code would struggle to detect the difference between using
and simply:
new Wrapper(); // note this doesn't dispose cleanly
Inner.Do();
Another issue with some static instance is that you'd also need to consider multiple nested blocks; would need a Stack<Wrapper>
, or you could cache the previous value to set it back to in the disposable object.