C# 如何将类固定到包含SqlConnection对象的内存中
如何将包含C# 如何将类固定到包含SqlConnection对象的内存中,c#,sql-server,C#,Sql Server,如何将包含SqlConnection对象的类实例“固定”在内存中。这样我就可以从该实例的IntPtr重新创建另一个SqlConnection对象,这样重新创建的SqlConnection也指向相同的SqlConnection对象。这样,如果我们与 bool success = object.ReferenceEquals(conn, conn2); 我尝试了这里给出的代码,甚至给出了[StructLayout(LayoutKind.Sequential)]属性,因为我在某个地方读到,类对象
SqlConnection
对象的类实例“固定”在内存中。这样我就可以从该实例的IntPtr
重新创建另一个SqlConnection
对象,这样重新创建的SqlConnection
也指向相同的SqlConnection
对象。这样,如果我们与
bool success = object.ReferenceEquals(conn, conn2);
我尝试了这里给出的代码,甚至给出了[StructLayout(LayoutKind.Sequential)]
属性,因为我在某个地方读到,类对象需要该属性才能固定
[StructLayout(LayoutKind.Sequential)]
public sealed class MyConnection
{
private SqlConnection _con = null;
public MyConnection(string oSqlServer,
string oDatabase,
string oUser,
string oPassword,
int oTimeOut = 20)
{
string connectionString = "Server=" + oSqlServer + ";" + "Database=" + oDatabase + ";" + "User=" + oUser + ";" + "Password=" + oPassword + ";" + "Trusted_Connection=false" + ";" + "Connection Timeout=" + oTimeOut + ";" + "Persist Security Info=False";
_con = new SqlConnection(connectionString);
}
public void Open()
{
_con.Open();
}
}
我用这些线来称呼它
MyConnection conn = new MyConnection("SqlServer2014", "Database1", "User1", "Password1", 11);
GCHandle handle = GCHandle.Alloc(conn, GCHandleType.Pinned);
IntPtr ip = handle.AddrOfPinnedObject();
然后使用相同的IntPtr
值执行此操作,并再次获取SqlConnection
对象
MyConnection conn2 = (GCHandle.FromIntPtr(ip).Target as MyConnection);
所以conn和conn2基本上都指向内存中的同一个对象,
所以这应该是真的
bool success = object.ReferenceEquals(conn, conn2);
这个类应该被钉住。但我犯了个错误
对象包含非基本数据或不可删除的数据
可能是因为SqlConnection对象。但是如果我们不希望堆内存中的
SqlConnection
实例更改位置,因为我正在使用addrofpindedobject()
这样我可以使用相同的IntPtr
获得一个GCHandle,并重新创建另一个SqlConnection
对象,该对象指向内存中已经存在的相同SqlConnection
,这样两个连接都指向内存中的相同对象。锁定MyConnection
不会锁定SqlConnection
。。。这听起来像是个XY问题。你为什么要这么做?据我所知,从DbConnection继承的每个连接在每次使用时都必须创建/释放,因为在后台有一个连接(池)管理器。为什么要这样做?SqlConnection实现了一个连接池,你应该努力使它尽可能短。无论你认为你能用它实现什么,这都不是正确的方法。不要跨作用域重用SqlConnection
对象,也不要在固定一次性对象时做一些有趣的事情。您最多可以共享连接字符串,以便“重新创建”连接SqlConnection
本身只不过是池连接对象的句柄;不应将其视为共享资源。不清楚您为什么认为它有用。但是不需要固定对象来生成IntPtr。改为使用GCHandle.ToIntPtr()。然后,您可以稍后使用FromIntPtr()取回GCHandle,其目标属性将取回对象引用。别忘了免费的。