我偶尔会抛出 System.Data.EntityException。异常表明连接上的握手时间很长。异常信息是:
System.Data.EntityException:基础提供程序在打开时失败。---> System.Data.SqlClient.SqlException:连接超时已过期。登录后阶段超时时间已过。连接可能在等待服务器完成登录过程并响应时超时;或者它可能在尝试创建多个活动连接时超时。尝试连接到此服务器所花费的持续时间是 - [登录前] 初始化 = 40;握手=25118;[登录] 初始化=0;身份验证=0;[登录后] 完成=4384;---> System.ComponentModel.Win32Exception:等待操作超时
请注意,“握手”阶段是 25.118 秒。鉴于连接和命令超时只有 30 次,出现问题也就不足为奇了。我的问题是。
- 这可能是什么原因造成的?
- 有没有办法监控一切正常时的连接时间?为了缩小问题的范围,我想知道建立连接是否总是需要很长时间,或者它是否通常非常快并且由于某种原因有时需要超过 30 秒。它可能会提供一些线索。
我不想只是增加连接/命令超时而不知道更多。我已经读过可以使用连接池,如果有理由我当然愿意尝试。我们使用的数据库是 SQL Express,代码不会在上下文中调用 dispose,但我读到这不是绝对必要的(例如:http ://blog.jongallant.com/2012/10/do-i-have -to-call-dispose-on-dbcontext.html)。事实上,代码非常相似。我们有一个像这样的类:
public class MyContext : DbContext
{
public MyContext (string dbName, bool setInitializer = true)
: base(dbName)
{
if (setInitializer)
{
Database.SetInitializer(new MyContextInitializer());
// Set timeout (based on code from http://stackoverflow.com/questions/6232633/entity-framework-timeouts)
var adapter = (IObjectContextAdapter) this;
var objectContext = adapter.ObjectContext;
objectContext.CommandTimeout = CommandTimeoutSeconds;
}
}
public DbSet<FuelReading> FuelReadings {get; set;}
}
internal class MyContextInitializer : DropCreateDatabaseIfModelChanges<MyContext>
{
/// <summary>
/// Adds initial values to the db on db creation.
/// </summary>
/// <param name="context"></param>
protected override void Seed(MyContext context)
{
// Seed
// TODO: Remove this seeding if we upgrade to .NET 4.5 (Entity Framework 5 has enum support on .NET 4.5)
var fuelReading= new fuelReading {Name = "Unknown"};
context.FuelReadings.Add(fuelReading);
base.Seed(context);
}
}
我看到异常的地方是这样的代码:
FuelReading reading= (from tz in _dbContext.FuelReadings
where
tz.Id ==
3
select tz).FirstOrDefault();
但我强调它也出现在其他地方。
我可以提供更多相关的细节吗?有没有人有任何想法?
更新。根据评论和朋友的建议,我开始关注 PerfMon。通常,“连接重置/秒”通过屋顶(到 300)。我在这个特定的柜台上找不到很多信息。从表面上看,它是一秒钟内重置连接的次数。这是否意味着尝试或建立了很多连接?我不确定为什么这个数字会变得如此之高,因为我认为(代码是继承的)数据库(SQLServer Express)只是写入对象中。这些对象是使用 LINQ 读取、操作、写入等的,但我认为在所有重要的 DbContext.SaveChanges(...) 之前,dB 不会再次发生任何事情,所以不确定这个计数器告诉我什么。然而,如果它确实反映了大量的联系,那么它可能是一个关于正在发生的事情的重要线索。