超时已过期。在获得连接第一次连接之前经过了超时时间

时间:2013-02-26 07:34:29

标签: c# sql-server design-patterns connection-pooling

我有这个问题。我已经用这个问题搜索了很多站点,但是他们都建议关闭所有连接,或者只是使用“using”连接和dataReader。但!我的问题在于我无法打开第一个连接!我在连接附近设置了一个断点,看到没有其他连接,所以,有第一个。当我重新打开从static到Singleton的连接的类时,这个问题很严重,这里是代码:

public class Storage
{
private static Storage instance;

public static Storage Instance
{
    get
    {
        if (instance == null)
        {
            instance = new Storage();
        }
        return instance;
    }
}

private Storage()
{
    Manager man = new Manager();
    products = man.LoadProducts();
    components = man.LoadComponents();
    man.LoadProductComponents();
}

public Dictionary<int, Product> Products
    {
        get { return products; }
        set { products = value; }
    }

public Dictionary<int, Component> Components
    {
        get { return components; }
        set { components = value; }
    }

private Dictionary<int, Product> products;
private Dictionary<int, Component> components;

}

这是一个Manager构造函数

    public Manager()
    {
        connection = new SqlConnection(@"Persist Security Info=False;User ID=user;Password=pass;Initial Catalog=Products;Server=(local)");
        if (connection.State != ConnectionState.Open) connection.Open();
    }

异常提升时,连接为Closed。有人有想法吗?

更新

如果我关闭合并 - 我在同一行有"System.StackOverflowException" in System.Data.dll

1 个答案:

答案 0 :(得分:1)

您的Manager班级会创建并打开一个连接:

public Manager()
{
    connection = new SqlConnection(@"Persist Security Info=False;User ID=user;Password=pass;Initial Catalog=Products;Server=(local)");
    if (connection.State != ConnectionState.Open) connection.Open();
}

但是,如果我们看一下你如何使用它,很明显没有任何东西关闭这个连接:

private Storage()
{
    Manager man = new Manager();
    products = man.LoadProducts();
    components = man.LoadComponents();
    man.LoadProductComponents();
}

我希望Manager能够实现IDisposable,并关闭Dispose()方法并释放连接:

class Manager : IDisposable
{
    ...
    public void Dispose()
    {
        if(connection != null) connection.Dispose();
        connection = null;
    }
}

然后将通过using使用:

private Storage()
{
    using(Manager man = new Manager())
    {
        products = man.LoadProducts();
        components = man.LoadComponents();
        man.LoadProductComponents();
    }
}

我担心的是,你的经理只是一个更广泛问题的一个例子:不要自己清理连接。当Manager是静态的时,这可能是非常不可见的,但是当切换到Manager个实例时,很容易将多个Manager对象旋转起来。每个都绑定一个连接,直到GC。