我经常使用看起来像这样的模式.我想知道这是否正常,或者是否有最佳实践我不在这里申请.
具体来说,我在想; 在抛出异常的情况下,我在finally块中的代码足以确保连接被正确关闭?
public class SomeDataClass : IDisposable
{
private SqlConnection _conn;
//constructors and methods
private DoSomethingWithTheSqlConnection()
{
//some code excluded for brevity
try
{
using (SqlCommand cmd = new SqlCommand(SqlQuery.CountSomething, _SqlConnection))
{
_SqlConnection.Open();
countOfSomething = Convert.ToInt32(cmd.ExecuteScalar());
}
}
finally
{
//is this the best way?
if (_SqlConnection.State == ConnectionState.Closed)
_SqlConnection.Close();
}
//some code excluded for brevity
}
public Dispose()
{
_conn.Dispose();
}
}
Run Code Online (Sandbox Code Playgroud) HttpContext在我的ASP.NET MVC应用程序中存在持久HTTP连接(如SignalR集线器)时,我在管理使用StructureMap的开放式数据库连接的生命周期时遇到了问题.
我的DI容器StructureMap IDbConnection为几个服务注入了一个open .为了确保关闭并妥善处理这些数据库连接,我调用ObjectFactory.ReleaseAndDisposeAllHttpScopedObjects()了该EndRequest事件.
这对于MVC控制器非常有用,直到需要数据库连接的服务注入到SignalR集线器中,这会为每个客户端保持持久的HTTP连接,并最终使连接池饱和.
如果我IDbConnection使用单一范围,每个应用程序只打开一个连接,并且池不会饱和,但如果连接被锁定或超时,这是一个坏主意.
那么也许有一种方法可以自定义SignalR集线器的数据库连接范围?我尝试在每个Hub方法中解析服务实例,但这仍然在HttpContext范围内实例化数据库连接,并在调用客户端的集线器连接期间保持打开状态.
当存在持久的HTTP连接时,如何在HTTP范围的上下文中管理使用StructureMap的数据库连接的生命周期?
public class MyService
{
private IDbConnection _con;
public MyService(IDbConnection con)
{
_con = con;
}
public IEnumerable<string> GetStuff()
{
return _con.Select<string>("SELECT someString FROM SomeTable").ToList();
}
}
Run Code Online (Sandbox Code Playgroud)
public class MyHub : Hub
{
private MyService _service;
public MyHub(MyService service)
{
_service = service; // Oh Noes! This will open a database connection
// for each Client because of …Run Code Online (Sandbox Code Playgroud) 鉴于方法:
internal static DataSet SelectDataSet(String commandText, DataBaseEnum dataBase)
{
var dataset = new DataSet();
SqlConnection sqlc = dataBase == DataBaseEnum.ZipCodeDb
? new SqlConnection(ConfigurationManager.AppSettings["ZipcodeDB"])
: new SqlConnection(ConfigurationManager.AppSettings["WeatherDB"]);
SqlCommand sqlcmd = sqlc.CreateCommand();
sqlcmd.CommandText = commandText;
var adapter = new SqlDataAdapter(sqlcmd.CommandText, sqlc);
adapter.Fill(dataset);
return dataset;
}
Run Code Online (Sandbox Code Playgroud)
为什么sqlc(SqlConnection)在调用方法超出范围后没有处理/关闭,或者sqlc没有更多的引用?
编辑1: 即使将其包装在使用中,我仍然可以看到连接使用(我已关闭连接池):
SELECT DB_NAME(dbid) as 'Database Name',
COUNT(dbid) as 'Total Connections'
FROM sys.sysprocesses WITH (nolock)
WHERE dbid > 0
GROUP BY dbid
Run Code Online (Sandbox Code Playgroud)
编辑2: 在我从这里得到的帮助下进行一些调试 - 答案是有人硬编码连接字符串与池.感谢所有的帮助 - 如果可以的话,我会将所有回复标记为答案.
c# ×2
.net ×1
asp.net ×1
asp.net-mvc ×1
idisposable ×1
lifetime ×1
signalr ×1
sql ×1
static ×1
structuremap ×1