Singleton上的StackOverflowException

时间:2018-04-24 14:40:01

标签: c# oracle singleton

我的Singleton正在抛出一个StackOverflowException,但昨天它工作正常,唯一的变化是连接字符串中的数据库。它是一个控制台应用程序,调试非常复杂:

class OracleSingleton
{
    private static OracleConnection instance;

    private OracleSingleton() { }

    public static OracleConnection Instance
    {
        get
        {
            if (instance == null)
            {
                try
                {
                    instance = new OracleConnection(ConfigurationManager.ConnectionStrings["OracleConnection"].ConnectionString);
                }
                catch (Exception ex)
                {
                    LogHelper.WriteMessage("Error trying to create a new connection. - " + ex.Message.ToString() + " - " + ex.InnerException.ToString().Trim());
                }
            }
            return instance;
        }
    }
}

我的App.config:

<configuration>
  <connectionStrings>
    <add name="OracleConnection" connectionString="Password=somepassword;Persist Security Info=True;User ID=someuser;Data Source=DATABASE01"/>
  </connectionStrings>
    //Some stuff
</configuration>

你们能告诉我什么是错的,为什么昨天它运作正常?

修改

我使用Singleton做了很多事情。我知道问题出现在单例中,因为我的应用程序显示StackoverflowException没有记录任何东西,谁是我使用Singleton的地方之一。下面是我的LogHelper.WriteMessage方法,他在第一行程序中调用&#34;嗨,应用程序现在正在运行&#34;:

public static void WriteMessage(string info)
{
    using (OracleConnection conn = OracleSingleton.Instance)
    {
        using (OracleCommand cmd = new OracleCommand("INSERT INTO TB_LOG (DT_LOG, ID_PERMISSAO, ID_USUARIO, NM_USUARIO, DS_LOG) VALUES (TO_CHAR (SYSDATE, 'MM-DD-YYYY HH24:MI:SS'), 5025, 5025, 'IMPORTADORCAIXA', '" + info + "')", conn))
        {
            try
            {
                conn.Open();
                cmd.ExecuteNonQuery();
            } catch (Exception ex)
            {
                Console.WriteLine(DateTime.Now + " - Erro ao conectar com o banco. por favor, verifique o erro: " + ex.Message.ToString() + ", " + cmd.CommandText.ToString());
            }
        }
    }
    new LogHelper();
    eventLog.WriteEntry(info);
    Console.WriteLine(DateTime.Now + " - " + info);
    }

1 个答案:

答案 0 :(得分:4)

你的“单身”在某些路径上确实是递归的。如果这行

会发生什么
instance = new OracleConnection(ConfigurationManager.ConnectionStrings["OracleConnection"].ConnectionString);

抛出异常,例如,如果连接字符串无效?您使用WriteLog记录该异常,再次使用

引用单例
using (OracleConnection conn = OracleSingleton.Instance)

因此,如果连接字符串无效,或者连接创建因其他原因而不断失败 - 您将进行递归,并最终在堆栈空间耗尽时以StackOverflowException结束。

顺便说一下,

using (OracleConnection conn = OracleSingleton.Instance)

您还会处置您的连接,使其无法用于后续调用。

解决它的最佳方法是摆脱单身,没有必要。拥有全局连接是不好的做法 - 只需在每次需要时创建它并在完成后进行处理(关闭)。连接池将为您管理其余部分。

如果您因某些原因不想进行严重的重构,至少应该改为:

public static OracleConnection Create() {
    // no need to catch any exceptions here
    return new OracleConnection(ConfigurationManager.ConnectionStrings["OracleConnection"].ConnectionString);
}

并按照您的要求使用:

using (OracleConnection conn = OracleSingleton.Create())