gpt4 book ai didi

.net - 来自线程的 Entity Framework 连接管理

转载 作者:行者123 更新时间:2023-12-05 01:08:39 24 4
gpt4 key购买 nike

在我的多线程 Windows 服务中,我在每个线程上打开与 db 的连接,然后我处理这些连接,但问题是当我对 sys.sysprocesses 表执行查询时,有些连接没有在 db 上关闭。

我运行了两个单元测试并看到了一些奇怪的行为,首先我运行了一个包含 100 个任务的循环,然后在每个任务中打开一个新连接。这些完成后(我通过 WaitAll() 看到)我看到一些连接仍然卡在数据库中。
在第二个单元测试中,当我在没有并行执行的情况下运行多个 open/dispose 时,它​​会很好地处理它们并且我的数据库中没有挂起的连接。

问题是,在我的 Windows 服务中,这些挂起的连接被加起来,最后没有更多的地方可以放置新的连接,数据库变得对用户不可用。

这是代码,第一个是并行的,第二个不是:

    [TestMethod]
public void TestMultiThreadedAccessToExplicitObjectContext()
{
int taskSize = 100;
List<Task> taskList = new List<Task>();
int goodSources = 0;
for (int i = 0; i < taskSize; i++)
{
Task newTask = Task.Factory.StartNew(() =>
{
System.Data.Objects.ObjectContext objectContext = new PersoniteEntities();
objectContext.Connection.Open();
objectContext.Dispose();
Thread.Sleep(1200);
});

taskList.Add(newTask);
}

Task.WaitAll(taskList.ToArray());
GC.Collect();
total += goodSources;
}

[TestMethod]
public void TestMultiThreadedAccessToExplicitObjectContextInline()
{
System.Data.Objects.ObjectContext objectContext1 = new PersoniteEntities();
objectContext1.Connection.Open();
objectContext1.Dispose();

System.Data.Objects.ObjectContext objectContext2 = new PersoniteEntities();
objectContext2.Connection.Open();
objectContext2.Dispose();

System.Data.Objects.ObjectContext objectContext3 = new PersoniteEntities();
objectContext3.Connection.Open();
objectContext3.Dispose();

System.Data.Objects.ObjectContext objectContext4 = new PersoniteEntities();
objectContext4.Connection.Open();
objectContext4.Dispose();

System.Data.Objects.ObjectContext objectContext5 = new PersoniteEntities();
objectContext5.Connection.Open();
objectContext5.Dispose();
}

谢谢

最佳答案

使用连接池,每个工作进程(或在本例中的线程)都有自己的连接池。因此,如果您将 Max Pool Size 设置为 3,并生成 100x 个线程,则可能有 300 个连接。

来自有类似问题的人的更多信息:

ODP.NET Connection Pooling Parameters

还有一些来自 MS 的关于连接池如何工作的文档,以及连接池碎片的解释:

MSDN - SQL Server Connection Pooling (ADO.NET)

解决方案 1

在连接字符串中关闭连接池

MSDN - Connection String - Pooling

When the value of this key is set to true, any newly created connection will be added to the pool when closed by the application. In a next attempt to open the same connection, that connection will be drawn from the pool. Connections are considered the same if they have the same connection string. Different connections have different connection strings.

The value of this key can be "true", "false", "yes", or "no".



例如:
<add 
name="AppEntities"
connectionString="
metadata=res://*/App_Code.AppModel.csdl|res://*/App_Code.AppModel.ssdl|res://*/App_Code.AppModel.msl;
provider=System.Data.SqlClient;
provider connection string=&quot;
Data Source=.;
Initial Catalog=Example;
Integrated Security=True;
Pooling=False;
MultipleActiveResultSets=True
&quot;"
providerName="System.Data.EntityClient"
/>

解决方案 2

看起来可能有一个涉及信号量的解决方法,详细信息如下:

Database connection pooling with multi-threaded service

关于.net - 来自线程的 Entity Framework 连接管理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16884559/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com