我的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);
}
答案 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())