C# 在未涉及的类中检测调用是否包装在使用另一个

C# 在未涉及的类中检测调用是否包装在使用另一个,c#,design-patterns,singleton,using,C#,Design Patterns,Singleton,Using,首先,很抱歉问了这么难的题目,但我想不出比这更好的了。 如果有人知道更好的描述,我很乐意更改标题!:) 假设我有以下两个类的代码: using(new Wrapper()) { Inner.Do(); } public class Wrapper : IDisposable { public static Wrapper Instance { get; set; } public Wrapper() { Instance = this;

首先,很抱歉问了这么难的题目,但我想不出比这更好的了。 如果有人知道更好的描述,我很乐意更改标题!:)

假设我有以下两个类的代码:

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 */ }
    }
}
上面的代码按预期工作,我能够检测到我的代码是否包含在using语句中

不幸的是,静态实例变量是我能想到的实现上述目标的最佳方式,但它肯定不是最佳情况。 假设两个线程同时执行上述代码。一个线程将覆盖另一个线程的实例,导致未接受的beaviour和race条件

问题:

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 */ }
    }
}
有没有人能告诉我一个解决方案,在这个解决方案中,我仍然能够完成上述任务,但不使用静态实例变量

提前谢谢

回答

由于这只是对一些新内容的测试,所以我现在使用ThreadStaticAttribute。 但正如Marc Gravell所说,如果正在进行异步操作,则不要使用此选项


用法见克里斯·范德莫顿的答案。

我个人的建议很简单:不需要这样做。你是对的,没有神奇的方法可以做到这一点。线程问题可以通过
[ThreadStatic]
处理,但如果涉及多个线程,例如
async
,则无法很好地解决。如果可能,我会说:找到一种不同的实现策略,它不需要使用块检测不相关的
。同样,您的代码将很难检测到使用
和简单地:

new Wrapper(); // note this doesn't dispose cleanly
Inner.Do();

一些静态实例的另一个问题是,您还需要考虑多个嵌套块;将需要一个

堆栈
,或者您可以缓存上一个值以将其设置回一次性对象中。

您需要使用ThreadStatic属性标记支持实例属性的字段,如下所示:

[ThreadStatic]
private static Wrapper instance;

public static Wrapper Instance
{
    get { return instance; }
}
另见


您可能还需要处理重入(即嵌套使用)。

这是一个很好的答案!我将把它标记为正确,并在我的原始问题中写一些东西。一定要看!我将编辑我的问题。你能解释一下为什么多线程不能很好地工作,因为(据我所知)这个属性的用例是多线程的吗?