自从更新到EF6后,我发现了一些奇怪的事情,不确定这是否相关,但过去是好的
我正在做一组工作,然后将其保存到DB,然后再做另一个,保存另一个。
过了一会儿,我通过sp_who2
检查SQL服务器,发现我的电脑上有很多死连接。
工作量巨大然后有700个连接, 我必须在周期中手动杀死它们。
程序如:
while (jobDone == false)
{
var returnData=doOneSetJob();
myEntity dbconn= new myEntity;
foreach( var one in retrunData)
{
dbconn.targetTable.add(one );
try
{
dbconn.savechange();
/// even i put a dispose() here , still lots of dead connections
}
catch
{
console.writeline("DB Insertion Fail.");
dbconn.dispose();
dbconn= new myEntity();
}
}
dbconn.dispose()
}
答案 0 :(得分:2)
您应该考虑重构代码,以便在作业完成后清理您的连接。例如:
using (var context = new DbContext())
{
while (!jobDone)
{
// Execute job and get data
var returnData = doOneSetJob();
// Process job results
foreach (var one in returnData)
{
try
{
context.TargetTable.Add(one);
context.SaveChanges();
}
catch (Exception ex)
{
// Log the error
}
}
}
}
using
语句将保证您的上下文得到正确清理,即使在循环结果时发生错误也是如此。
答案 1 :(得分:1)
在这种情况下,您应该使用using
语句。取自MSDN:
using语句确保即使在对象上调用方法时发生异常,也会调用Dispose。您可以通过将对象放在try块中然后在finally块中调用Dispose来实现相同的结果;实际上,这就是编译器如何翻译using语句。
所以,你的代码看起来会更好:
using(var dbconn = new DbContext())
{
while (!jobDone)
{
foreach(var one in retrunData)
{
try
{
targetTable row = new TargetTable();
dbconn.TargetTable.add(row);
dbconn.SaveChanges();
}
catch (Exception ex)
{
Console.WriteLine("DB Insertion Fail.");
}
}
}
}
这样,即使您的代码在某些时候失败,Context
,资源和连接也会得到妥善处理。